diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs index 85e3dfc17a..29f6ea4ec1 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs @@ -28,20 +28,5 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads { return mark.IsVisibleInBookmarkPad && mark is BreakpointBookmark; } - - /* - protected override void OnItemActivated(SDBookmark bookmark) - { - if (bookmark is DecompiledBreakpointBookmark) { - // get information from breakpoint and navigate to the decompiled type - string assemblyFile, typeName; - if (DecompiledBreakpointBookmark.GetAssemblyAndType(bookmark.FileName, out assemblyFile, out typeName)) { - NavigationService.NavigateTo(assemblyFile, typeName, string.Empty, bookmark.LineNumber, false); - } - throw new NotImplementedException(); - } else { - base.OnItemActivated(bookmark); - } - }*/ } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs index ada5eab5dc..4eaf8b20d2 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs @@ -2,34 +2,25 @@ // This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt) using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Text; using System.Windows.Forms; using Debugger; using Debugger.AddIn; using Debugger.AddIn.Tooltips; using Debugger.AddIn.TreeModel; using Debugger.Interop.CorPublish; -using Debugger.MetaData; using ICSharpCode.Core; using ICSharpCode.Core.WinForms; using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.Semantics; -using ICSharpCode.SharpDevelop.Editor.Bookmarks; using ICSharpCode.SharpDevelop.Debugging; using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Gui; -using ICSharpCode.SharpDevelop.Gui.OptionPanels; using ICSharpCode.SharpDevelop.Project; -using Mono.Cecil; using Process = Debugger.Process; using StackFrame = Debugger.StackFrame; using TreeNode = Debugger.AddIn.TreeModel.TreeNode; @@ -87,7 +78,7 @@ namespace ICSharpCode.SharpDevelop.Services ICorPublish corPublish; - internal IDebuggerDecompilerService debuggerDecompilerService; + List symbolSources = new List(); /// public bool BreakAtBeginning { get; set; } @@ -357,8 +348,8 @@ namespace ICSharpCode.SharpDevelop.Services public void InitializeService() { - // get decompiler service - debuggerDecompilerService = SD.GetService(); + symbolSources.Add(new PdbSymbolSource()); + symbolSources.AddRange(AddInTree.BuildItems("/SharpDevelop/Services/DebuggerService/SymbolSource", null, false)); // init NDebugger CurrentDebugger = new NDebugger(); @@ -407,44 +398,7 @@ namespace ICSharpCode.SharpDevelop.Services void AddBreakpoint(BreakpointBookmark bookmark) { - Breakpoint breakpoint = null; - - #warning decompiler - /*if (bookmark is DecompiledBreakpointBookmark) { - try { - if (debuggerDecompilerService == null) { - LoggingService.Warn("No IDebuggerDecompilerService found!"); - return; - } - var dbb = (DecompiledBreakpointBookmark)bookmark; - MemberReference memberReference = null; - - string assemblyFile, typeName; - if (DecompiledBreakpointBookmark.GetAssemblyAndType(dbb.FileName, out assemblyFile, out typeName)) { - memberReference = dbb.GetMemberReference(debuggerDecompilerService.GetAssemblyResolver(assemblyFile)); - } - - int token = memberReference.MetadataToken.ToInt32(); - if (!debuggerDecompilerService.CheckMappings(token)) - debuggerDecompilerService.DecompileOnDemand(memberReference as TypeDefinition); - - int[] ilRanges; - int methodToken; -// if (debuggerDecompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) { -// CurrentDebugger.AddILBreakpoint(memberReference.FullName, dbb.LineNumber, memberReference.MetadataToken.ToInt32(), methodToken, ilRanges[0], dbb.IsEnabled); -// } - } catch (System.Exception ex) { - LoggingService.Error("Error on DecompiledBreakpointBookmark: " + ex.Message); - } - } else {*/ - breakpoint = CurrentDebugger.AddBreakpoint(bookmark.FileName, bookmark.LineNumber, 0, bookmark.IsEnabled); - //} - - if (breakpoint == null) { - LoggingService.Warn(string.Format("unable to create breakpoint: {0}", bookmark.ToString())); - return; - } - + Breakpoint breakpoint = CurrentDebugger.AddBreakpoint(bookmark.FileName, bookmark.LineNumber, 0, bookmark.IsEnabled); bookmark.InternalBreakpointObject = breakpoint; bookmark.IsHealthy = (CurrentProcess == null) || breakpoint.IsSet; bookmark.IsEnabledChanged += delegate { breakpoint.IsEnabled = bookmark.IsEnabled; }; @@ -512,6 +466,10 @@ namespace ICSharpCode.SharpDevelop.Services CurrentThread = e.Thread; CurrentStackFrame = CurrentThread != null ? CurrentThread.MostRecentUserStackFrame : null; + // Select the symbol source + var symbolSource = symbolSources.FirstOrDefault(s => CurrentStackFrame == null || s.HasSymbols(CurrentStackFrame.MethodInfo)); + CurrentProcess.SymbolSource = symbolSource ?? symbolSources.First(); + // We can have several events happening at the same time bool breakProcess = e.Break; @@ -642,73 +600,14 @@ namespace ICSharpCode.SharpDevelop.Services SD.Workbench.MainWindow.Activate(); - // if (debuggedProcess.IsSelectedFrameForced()) { if (CurrentStackFrame.HasSymbols) { SequencePoint nextStatement = CurrentStackFrame.NextStatement; if (nextStatement != null) { DebuggerService.RemoveCurrentLineMarker(); DebuggerService.JumpToCurrentLine(nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn); } - } else { - #warning JumpToDecompiledCode(CurrentStackFrame); - } -// } else { -// var frame = debuggedProcess.SelectedThread.MostRecentStackFrame; -// // other pause reasons -// if (frame != null && frame.HasSymbols) { -// JumpToSourceCode(); -// } else { -// // use most recent stack frame because we don't have the symbols -// JumpToDecompiledCode(debuggedProcess.SelectedThread.MostRecentStackFrame); -// } -// } - } - - /* - void JumpToDecompiledCode(Debugger.StackFrame frame) - { - if (frame == null) { - LoggingService.Error("No stack frame!"); - return; - } - - if (debuggerDecompilerService == null) { - LoggingService.Warn("No IDebuggerDecompilerService found!"); - return; - } - - // check for options - if these options are enabled, debugging decompiled code should not continue - if (!CurrentProcess.Options.DecompileCodeWithoutSymbols) { - LoggingService.Info("Decompiled code debugging is disabled!"); - return; - } - DebuggerService.RemoveCurrentLineMarker(); - // get external data - int typeToken = frame.MethodInfo.DeclaringType.MetadataToken; - int methodToken = frame.MethodInfo.MetadataToken; - int ilOffset = frame.IP; - int[] ilRanges = null; - int line = -1; - bool isMatch = false; - var debugType = (DebugType)frame.MethodInfo.DeclaringType; - debuggerDecompilerService.DebugStepInformation = Tuple.Create(methodToken, ilOffset); - - if (debuggerDecompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) { - // update marker & navigate to line - NavigationService.NavigateTo(debugType.DebugModule.FullPath, - debugType.FullNameWithoutGenericArguments, - IDStringProvider.GetIDString(frame.MethodInfo), - line); - } else - { - // no line => do decompilation - NavigationService.NavigateTo(debugType.DebugModule.FullPath, - debugType.FullNameWithoutGenericArguments, - IDStringProvider.GetIDString(frame.MethodInfo)); - } } - */ StopAttachedProcessDialogResult ShowStopAttachedProcessDialog() { diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs index 4677978d07..e3688abf78 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs @@ -256,23 +256,6 @@ namespace Debugger.AddIn.TreeModel } } else { WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger; - #warning decompiler - /* - if (debugger.debuggerDecompilerService != null) { - int typeToken = stackFrame.MethodInfo.DeclaringType.MetadataToken; - int methodToken = stackFrame.MethodInfo.MetadataToken; - foreach (var localVar in debugger.debuggerDecompilerService.GetLocalVariables(typeToken, methodToken)) { - int index = ((int[])debugger.debuggerDecompilerService.GetLocalVariableIndex(typeToken, methodToken, localVar))[0]; - yield return new ValueNode("Icons.16x16.Local", localVar, () => { - var newStackFrame = GetCurrentStackFrame(); - if (newStackFrame.MethodInfo != stackFrame.MethodInfo) - throw new GetValueException("Expected stack frame: " + stackFrame.MethodInfo.ToString()); - - return newStackFrame.GetLocalVariableValue((uint)index); - }); - } - } - */ } } diff --git a/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs b/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs index b62aba8864..a7c819fc91 100644 --- a/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs +++ b/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs @@ -69,7 +69,7 @@ namespace Debugger public virtual bool SetBreakpoint(Module module) { - var seq = PDBSymbolSource.GetSequencePoint(module, this.FileName, this.Line, this.Column); + var seq = module.SymbolSource.GetSequencePoint(module, this.FileName, this.Line, this.Column); if (seq != null) { ICorDebugFunction corFuction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken); ICorDebugFunctionBreakpoint corBreakpoint = corFuction.GetILCode().CreateBreakpoint((uint)seq.ILOffset); @@ -80,45 +80,4 @@ namespace Debugger return false; } } - /* - public class ILBreakpoint : Breakpoint - { - public ILBreakpoint(string typeName, int line, int metadataToken, int memberToken, int offset, bool enabled) - : base(null, line, 0, enabled) - { - this.TypeName = typeName; - this.MetadataToken = metadataToken; - this.MemberMetadataToken = memberToken; - this.ILOffset = offset; - this.IsEnabled = enabled; - } - - public int MetadataToken { get; private set; } - - public int MemberMetadataToken { get; private set; } - - public int ILOffset { get; private set; } - - public override bool SetBreakpoint(Module module) - { - var currentModuleTypes = module.GetNamesOfDefinedTypes(); - // set the breakpoint only if the module contains the type - if (!currentModuleTypes.Contains(this.TypeName)) - return false; - - SourcecodeSegment segment = SourcecodeSegment.CreateForIL(module, this.Line, MemberMetadataToken, ILOffset); - if (segment == null) - return false; - try { - ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart); - corBreakpoint.Activate(this.IsEnabled ? 1 : 0); - corBreakpoints.Add(corBreakpoint); - - return true; - } catch { - return false; - } - } - } - */ } diff --git a/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj b/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj index b43319bf6b..ef2a7119d3 100644 --- a/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj +++ b/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj @@ -88,7 +88,7 @@ - + diff --git a/src/AddIns/Debugger/Debugger.Core/Eval.cs b/src/AddIns/Debugger/Debugger.Core/Eval.cs index 0675c415e7..d605a26d45 100644 --- a/src/AddIns/Debugger/Debugger.Core/Eval.cs +++ b/src/AddIns/Debugger/Debugger.Core/Eval.cs @@ -62,7 +62,7 @@ namespace Debugger case EvalState.Evaluating: throw new GetValueException("Evaluating..."); case EvalState.EvaluatedSuccessfully: return result; case EvalState.EvaluatedException: return result; - case EvalState.EvaluatedNoResult: return null; + case EvalState.EvaluatedNoResult: throw new DebuggerException("Evaluation did not return any value."); case EvalState.EvaluatedTimeOut: throw new GetValueException("Timeout"); default: throw new DebuggerException("Unknown state"); } diff --git a/src/AddIns/Debugger/Debugger.Core/LocalVariable.cs b/src/AddIns/Debugger/Debugger.Core/LocalVariable.cs index 2b4db11a75..1eca86ba14 100644 --- a/src/AddIns/Debugger/Debugger.Core/LocalVariable.cs +++ b/src/AddIns/Debugger/Debugger.Core/LocalVariable.cs @@ -51,12 +51,13 @@ namespace Debugger.MetaData public static List GetLocalVariables(IMethod method) { - if (!PDBSymbolSource.HasSymbols(method)) + var module = method.ParentAssembly.GetModule(); + if (!module.SymbolSource.HasSymbols(method)) return null; List localVariables = new List(); - foreach (ILLocalVariable ilvar in PDBSymbolSource.GetLocalVariables(method)) { + foreach (ILLocalVariable ilvar in module.SymbolSource.GetLocalVariables(method)) { int index = ilvar.Index; // NB: Display class does not have the compiler-generated flag if (ilvar.IsCompilerGenerated || ilvar.Name.StartsWith("CS$")) { diff --git a/src/AddIns/Debugger/Debugger.Core/Module.cs b/src/AddIns/Debugger/Debugger.Core/Module.cs index c4ca94f7c8..d305de112a 100644 --- a/src/AddIns/Debugger/Debugger.Core/Module.cs +++ b/src/AddIns/Debugger/Debugger.Core/Module.cs @@ -46,6 +46,10 @@ namespace Debugger get { return process; } } + public ISymbolSource SymbolSource { + get { return this.Process.SymbolSource; } + } + NDebugger Debugger { get { return this.AppDomain.Process.Debugger; } } diff --git a/src/AddIns/Debugger/Debugger.Core/NDebugger.cs b/src/AddIns/Debugger/Debugger.Core/NDebugger.cs index 95932bddb1..b99431f703 100644 --- a/src/AddIns/Debugger/Debugger.Core/NDebugger.cs +++ b/src/AddIns/Debugger/Debugger.Core/NDebugger.cs @@ -170,13 +170,6 @@ namespace Debugger return breakpoint; } -// public ILBreakpoint AddILBreakpoint(string typeName, int line, int metadataToken, int memberToken, int offset, bool enabled) -// { -// ILBreakpoint breakpoint = new ILBreakpoint(typeName, line, metadataToken, memberToken, offset, enabled); -// AddBreakpoint(breakpoint); -// return breakpoint; -// } - void AddBreakpoint(Breakpoint breakpoint) { this.breakpoints.Add(breakpoint); diff --git a/src/AddIns/Debugger/Debugger.Core/Options.cs b/src/AddIns/Debugger/Debugger.Core/Options.cs index 1d75bfcc62..7c943cb7fd 100644 --- a/src/AddIns/Debugger/Debugger.Core/Options.cs +++ b/src/AddIns/Debugger/Debugger.Core/Options.cs @@ -6,17 +6,6 @@ namespace Debugger { public class Options { - public Options() - { - EnableJustMyCode = true; - StepOverNoSymbols = true; - StepOverDebuggerAttributes = true; - StepOverAllProperties = false; - StepOverFieldAccessProperties = true; - SymbolsSearchPaths = new string[0]; - PauseOnHandledExceptions = false; - } - public virtual bool EnableJustMyCode { get; set; } public virtual bool StepOverNoSymbols { get; set; } public virtual bool StepOverDebuggerAttributes { get; set; } diff --git a/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs b/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs index 848db8f057..578fdc4fe6 100644 --- a/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs +++ b/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs @@ -45,6 +45,11 @@ namespace Debugger this.From = from; this.To = to; } + + public override string ToString() + { + return string.Format("{0:X2}-{1:X2}", From, To); + } } public class ILLocalVariable @@ -56,7 +61,25 @@ namespace Debugger public ILRange[] ILRanges { get; set; } } - public class PDBSymbolSource + public interface ISymbolSource + { + /// Find sequence point by IL offset + SequencePoint GetSequencePoint(IMethod method, int iloffset); + + /// Find sequence point by source code location + SequencePoint GetSequencePoint(Module module, string filename, int line, int column); + + /// Determine whether the method is debugable + bool HasSymbols(IMethod method); + + /// Get IL ranges that should be always stepped over by the debugger + IEnumerable GetIgnoredILRanges(IMethod method); + + /// Get local variable metadata + IEnumerable GetLocalVariables(IMethod method); + } + + public class PdbSymbolSource : ISymbolSource { /// /// Get absolute source code path for the specified document. @@ -118,7 +141,7 @@ namespace Debugger } } - public static SequencePoint GetSequencePoint(IMethod method, int iloffset) + public SequencePoint GetSequencePoint(IMethod method, int iloffset) { var symMethod = method.GetSymMethod(); if (symMethod == null) @@ -149,14 +172,11 @@ namespace Debugger return sequencePoint; } - public static SequencePoint GetSequencePoint(Module module, string filename, int line, int column) + public SequencePoint GetSequencePoint(Module module, string filename, int line, int column) { // Do not use ISymUnmanagedReader.GetDocument! It is broken if two files have the same name // Do not use ISymUnmanagedMethod.GetOffset! It sometimes returns negative offset - if (filename == null || !Path.IsPathRooted(filename)) - throw new DebuggerException("Invalid filename. Absolute path is required."); - ISymUnmanagedReader symReader = module.SymReader; if (symReader == null) return null; // No symbols @@ -181,9 +201,7 @@ namespace Debugger int codesize = (int)corFunction.GetILCode().GetSize(); var seqPoints = symMethod.GetSequencePoints(codesize).Where(s => s.StartLine != 0xFEEFEE); SequencePoint seqPoint = null; - if (column == 0) { - seqPoint = seqPoints.FirstOrDefault(s => s.StartLine <= line && line <= s.EndLine); - } else { + if (column != 0) { seqPoint = seqPoints.FirstOrDefault(s => (s.StartLine < line || (s.StartLine == line && s.StartColumn <= column)) && (line < s.EndLine || (line == s.EndLine && column <= s.EndColumn))); } @@ -191,12 +209,12 @@ namespace Debugger return seqPoint; } - public static bool HasSymbols(IMethod method) + public bool HasSymbols(IMethod method) { return method.GetSymMethod() != null; } - public static IEnumerable GetIgnoredILRanges(IMethod method) + public IEnumerable GetIgnoredILRanges(IMethod method) { var symMethod = method.GetSymMethod(); if (symMethod == null) @@ -206,7 +224,7 @@ namespace Debugger return symMethod.GetSequencePoints(codeSize).Where(p => p.StartLine == 0xFEEFEE).SelectMany(p => p.ILRanges).ToList(); } - public static IEnumerable GetLocalVariables(IMethod method) + public IEnumerable GetLocalVariables(IMethod method) { var symMethod = method.GetSymMethod(); if (symMethod == null) diff --git a/src/AddIns/Debugger/Debugger.Core/Process.cs b/src/AddIns/Debugger/Debugger.Core/Process.cs index 0ec6a19724..b4cd2f0612 100644 --- a/src/AddIns/Debugger/Debugger.Core/Process.cs +++ b/src/AddIns/Debugger/Debugger.Core/Process.cs @@ -107,6 +107,8 @@ namespace Debugger public string Filename { get; private set; } + public ISymbolSource SymbolSource { get; set; } + public static DebugModeFlag DebugMode { get; set; } internal Process(NDebugger debugger, ICorDebugProcess corProcess, string filename, string workingDirectory) @@ -115,6 +117,7 @@ namespace Debugger this.corProcess = corProcess; this.workingDirectory = workingDirectory; this.Filename = System.IO.Path.GetFullPath(filename); // normalize path + this.SymbolSource = new PdbSymbolSource(); this.callbackInterface = new ManagedCallback(this); } @@ -452,7 +455,7 @@ namespace Debugger public void RunTo(string fileName, int line, int column) { foreach(Module module in this.Modules) { - SequencePoint seq = PDBSymbolSource.GetSequencePoint(module, fileName, line, column); + SequencePoint seq = this.SymbolSource.GetSequencePoint(module, fileName, line, column); if (seq != null) { ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken); ICorDebugFunctionBreakpoint corBreakpoint = corFunction.GetILCode().CreateBreakpoint((uint)seq.ILOffset); diff --git a/src/AddIns/Debugger/Debugger.Core/StackFrame.cs b/src/AddIns/Debugger/Debugger.Core/StackFrame.cs index c8bd23ebb6..4780446a78 100644 --- a/src/AddIns/Debugger/Debugger.Core/StackFrame.cs +++ b/src/AddIns/Debugger/Debugger.Core/StackFrame.cs @@ -46,7 +46,7 @@ namespace Debugger /// True if the stack frame has symbols defined. public bool HasSymbols { get { - return PDBSymbolSource.HasSymbols(this.MethodInfo); + return this.Module.SymbolSource.HasSymbols(this.MethodInfo); } } @@ -154,10 +154,11 @@ namespace Debugger void AsyncStep(bool stepIn) { List stepRanges = new List(); - var seq = PDBSymbolSource.GetSequencePoint(this.MethodInfo, this.IP); + var seq = this.Module.SymbolSource.GetSequencePoint(this.MethodInfo, this.IP); if (seq != null) { + Process.TraceMessage("Step over: {0} IL:{1}", seq, string.Join(" ", seq.ILRanges)); stepRanges.AddRange(seq.ILRanges); - stepRanges.AddRange(PDBSymbolSource.GetIgnoredILRanges(this.MethodInfo)); + stepRanges.AddRange(this.Module.SymbolSource.GetIgnoredILRanges(this.MethodInfo)); } // Remove overlapping and connected ranges @@ -195,7 +196,7 @@ namespace Debugger /// public SequencePoint NextStatement { get { - return PDBSymbolSource.GetSequencePoint(this.MethodInfo, this.IP); + return this.Module.SymbolSource.GetSequencePoint(this.MethodInfo, this.IP); } } @@ -203,7 +204,7 @@ namespace Debugger { this.Process.AssertPaused(); - var seq = PDBSymbolSource.GetSequencePoint(this.Module, filename, line, column); + var seq = this.Module.SymbolSource.GetSequencePoint(this.Module, filename, line, column); if (seq != null && seq.MethodDefToken == this.MethodInfo.GetMetadataToken()) { try { if (dryRun) { @@ -232,7 +233,7 @@ namespace Debugger if (loc.IsThis) return loc.GetValue(this); } - return null; + throw new GetValueException("The current method does not have 'this'."); } else { return new Value(this.AppDomain, GetThisCorValue()); } @@ -240,7 +241,8 @@ namespace Debugger ICorDebugValue GetThisCorValue() { - if (this.MethodInfo.IsStatic) throw new GetValueException("Static method does not have 'this'."); + if (this.MethodInfo.IsStatic) + throw new GetValueException("Static method does not have 'this'."); ICorDebugValue corValue; try { corValue = CorILFrame.GetArgument(0); @@ -347,7 +349,7 @@ namespace Debugger Options opt = this.Process.Options; if (opt.StepOverNoSymbols) { - if (!PDBSymbolSource.HasSymbols(this.MethodInfo)) return true; + if (!this.Module.SymbolSource.HasSymbols(this.MethodInfo)) return true; } if (opt.StepOverDebuggerAttributes) { string[] debuggerAttributes = { diff --git a/src/AddIns/Debugger/Debugger.Core/Value.cs b/src/AddIns/Debugger/Debugger.Core/Value.cs index b1753b7f3e..03ad6157d3 100644 --- a/src/AddIns/Debugger/Debugger.Core/Value.cs +++ b/src/AddIns/Debugger/Debugger.Core/Value.cs @@ -14,6 +14,10 @@ namespace Debugger { public delegate Value ValueGetter(StackFrame context); + /// + /// Thrown when Value can not be obtained. + /// Methods should throw this exception instead of returning null. + /// public class GetValueException: DebuggerException { public GetValueException(string error) : base(error) {} @@ -240,13 +244,13 @@ namespace Debugger } /// Dereferences a pointer type - /// Returns null for a null pointer public Value Dereference() { - if (this.Type.Kind != TypeKind.Pointer) throw new DebuggerException("Not a pointer"); + if (this.Type.Kind != TypeKind.Pointer) + throw new DebuggerException("Not a pointer"); ICorDebugReferenceValue corRef = (ICorDebugReferenceValue)this.CorValue; if (corRef.GetValue() == 0 || corRef.Dereference() == null) { - return null; + throw new GetValueException("Null pointer"); } else { return new Value(this.AppDomain, corRef.Dereference()); } @@ -394,18 +398,6 @@ namespace Debugger } } - /* - /// Get a field or property of an object with a given name. - /// Null if not found - public Value GetMemberValue(Thread evalThread, string name) - { - MemberInfo memberInfo = this.Type.GetMembers(m => m.Name == name && (m.IsFieldOrNonIndexedProperty), GetMemberOptions.None); - if (memberInfo == null) - return null; - return GetMemberValue(evalThread, memberInfo); - } - */ - /// Get the value of given member. public Value GetMemberValue(Thread evalThread, IMember memberInfo, params Value[] arguments) { diff --git a/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs b/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs index bce0805d30..308478de5a 100644 --- a/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs +++ b/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs @@ -200,6 +200,15 @@ namespace Debugger.Tests testNode.SetAttribute("name", testName); shapshotID = 0; + debugger.Options = new Options(); + debugger.Options.EnableJustMyCode = true; + debugger.Options.StepOverNoSymbols = true; + debugger.Options.StepOverDebuggerAttributes = true; + debugger.Options.StepOverAllProperties = false; + debugger.Options.StepOverFieldAccessProperties = true; + debugger.Options.SymbolsSearchPaths = new string[0]; + debugger.Options.PauseOnHandledExceptions = false; + log = ""; lastLogMessage = null; process = debugger.Start(exeFilename, Path.GetDirectoryName(exeFilename), testName, false); diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs deleted file mode 100644 index 5b5666df7e..0000000000 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs +++ /dev/null @@ -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; - } - - /// - /// Stores the decompilation information. - /// - public class DebuggerDecompilerService : IDebuggerDecompilerService - { - ILSpyAssemblyResolver resolver; - - static DebuggerDecompilerService() - { - DebugInformation = new ConcurrentDictionary(); - ProjectService.SolutionClosed += delegate { - DebugInformation.Clear(); - GC.Collect(); - }; - } - - internal static IDebuggerDecompilerService Instance { get; private set; } - - /// - /// Gets or sets the external debug information. - /// This constains the code mappings and local variables. - /// - internal static ConcurrentDictionary DebugInformation { get; private set; } - - public DebuggerDecompilerService() - { - Instance = this; - } - - public Tuple 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 GetLocalVariables(int typeToken, int memberToken) - { - if (DebugInformation == null || !DebugInformation.ContainsKey(typeToken)) - yield break; - - var externalData = DebugInformation[typeToken]; - IEnumerable 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 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; - } - } - */ -} diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerTextOutput.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerTextOutput.cs index b13cfd3c4d..a8e99300e5 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerTextOutput.cs +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerTextOutput.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using ICSharpCode.Core; using ICSharpCode.Decompiler; using Mono.Cecil; @@ -13,7 +14,7 @@ namespace ICSharpCode.ILSpyAddIn { readonly ITextOutput output; - public readonly List DebuggerMemberMappings = new List(); + public readonly Dictionary DebugSymbols = new Dictionary(); public readonly Dictionary MemberLocations = new Dictionary(); public DebuggerTextOutput(ITextOutput output) @@ -63,10 +64,12 @@ namespace ICSharpCode.ILSpyAddIn output.WriteReference(text, reference, isLocal); } - public void AddDebuggerMemberMapping(MemberMapping memberMapping) + public void AddDebugSymbols(MethodDebugSymbols methodDebugSymbols) { - DebuggerMemberMappings.Add(memberMapping); - output.AddDebuggerMemberMapping(memberMapping); + var id = XmlDocKeyProvider.GetKey(methodDebugSymbols.CecilMethod); + methodDebugSymbols.SequencePoints = methodDebugSymbols.SequencePoints.OrderBy(s => s.ILOffset).ToList(); + this.DebugSymbols.Add(id, methodDebugSymbols); + output.AddDebugSymbols(methodDebugSymbols); } public void MarkFoldStart(string collapsedText, bool defaultCollapsed) diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin index 5c7ba7c19f..26e4f5eec0 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin @@ -12,6 +12,10 @@ + + + + diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj index 230f120d34..e0218efa12 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj @@ -52,6 +52,7 @@ 3.5 + 4.0 @@ -64,8 +65,8 @@ Properties\GlobalAssemblyInfo.cs - + @@ -75,7 +76,6 @@ SetILSpyPathDialog.cs - SetILSpyPathDialog.cs @@ -119,6 +119,10 @@ ICSharpCode.Core False + + {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} + Debugger.Core + {0162E499-42D0-409B-AA25-EED21F75336B} AvalonEdit.AddIn diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpySymbolSource.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpySymbolSource.cs new file mode 100644 index 0000000000..23bba2f4ad --- /dev/null +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpySymbolSource.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Debugger; +using ICSharpCode.Core; +using ICSharpCode.Decompiler; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.Documentation; +using ICSharpCode.NRefactory.TypeSystem; + +namespace ICSharpCode.ILSpyAddIn +{ + public class ILSpySymbolSource : ISymbolSource + { + public static MethodDebugSymbols GetSymbols(IMethod method) + { + // Use the non-specialised method definition to look up decompiled symbols + var id = IdStringProvider.GetIdString(method.MemberDefinition); + var content = DecompiledViewContent.Get(method); + if (content != null && content.DebugSymbols.ContainsKey(id)) { + return content.DebugSymbols[id]; + } + return null; + } + + public Debugger.SequencePoint GetSequencePoint(IMethod method, int iloffset) + { + var symbols = GetSymbols(method); + if (symbols == null) + return null; + + var content = DecompiledViewContent.Get(method); + var seqs = symbols.SequencePoints; + var seq = seqs.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)); + if (seq == null) + seq = seqs.FirstOrDefault(p => iloffset <= p.ILOffset); + if (seq != null) { + // Use the widest sequence point containing the IL offset + iloffset = seq.ILOffset; + seq = seqs.Where(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) + .OrderByDescending(p => p.ILRanges.Last().To - p.ILRanges.First().From) + .FirstOrDefault(); + return seq.ToDebugger(symbols, content.VirtualFileName); + } + return null; + } + + public Debugger.SequencePoint GetSequencePoint(Module module, string filename, int line, int column) + { + var content = DecompiledViewContent.Get(new FileName(filename)); + if (content == null) + return null; + if (!FileUtility.IsEqualFileName(module.FullPath, content.AssemblyFile)) + return null; + + TextLocation loc = new TextLocation(line, column); + foreach(var symbols in content.DebugSymbols.Values.Where(s => s.StartLocation <= loc && loc <= s.EndLocation)) { + Decompiler.SequencePoint seq = null; + if (column != 0) + seq = symbols.SequencePoints.FirstOrDefault(p => p.StartLocation <= loc && loc <= p.EndLocation); + if (seq == null) + seq = symbols.SequencePoints.FirstOrDefault(p => line <= p.StartLocation.Line); + if (seq != null) + return seq.ToDebugger(symbols, content.VirtualFileName); + } + return null; + } + + public bool HasSymbols(IMethod method) + { + var symbols = GetSymbols(method); + return symbols != null && symbols.SequencePoints.Any(); + } + + public IEnumerable GetIgnoredILRanges(IMethod method) + { + var symbols = GetSymbols(method); + if (symbols == null) + return new ILRange[] { }; + + int codesize = symbols.CecilMethod.Body.CodeSize; + var inv = ICSharpCode.Decompiler.ILAst.ILRange.Invert(symbols.SequencePoints.SelectMany(s => s.ILRanges), codesize); + return inv.Select(r => new ILRange(r.From, r.To)); + } + + public IEnumerable GetLocalVariables(IMethod method) + { + var symbols = GetSymbols(method); + if (symbols == null) + return null; + + return symbols.LocalVariables.Select(v => new Debugger.ILLocalVariable() { + Index = v.OriginalVariable.Index, + Type = method.Compilation.FindType(KnownTypeCode.Object), // TODO + Name = v.Name, + IsCompilerGenerated = false, + ILRanges = new [] { new Debugger.ILRange(0, int.MaxValue) } + }); + } + } + + static class ILSpySymbolSourceExtensions + { + public static Debugger.SequencePoint ToDebugger(this ICSharpCode.Decompiler.SequencePoint seq, ICSharpCode.Decompiler.MethodDebugSymbols symbols, string filename) + { + return new Debugger.SequencePoint() { + MethodDefToken = symbols.CecilMethod.MetadataToken.ToUInt32(), + ILRanges = seq.ILRanges.Select(r => new ILRange(r.From, r.To)).ToArray(), + Filename = filename, + StartLine = seq.StartLocation.Line, + StartColumn = seq.StartLocation.Column, + EndLine = seq.EndLocation.Line, + EndColumn = seq.EndLocation.Column, + }; + } + } +} diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs index 42a72ee007..30b77d1ffe 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs @@ -8,7 +8,6 @@ using ICSharpCode.Core; using ICSharpCode.NRefactory.Documentation; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Gui; namespace ICSharpCode.ILSpyAddIn { @@ -54,45 +53,5 @@ namespace ICSharpCode.ILSpyAddIn } SD.Workbench.ShowView(new DecompiledViewContent(assemblyFile, typeName, entityIdString)); } - - /* - public bool NavigateToMember(FileName assemblyFile, string typeName, string entityTag, int lineNumber, bool updateMarker) - { - if (string.IsNullOrEmpty(assemblyFile)) - throw new ArgumentException("assemblyFile is null or empty"); - - if (string.IsNullOrEmpty(typeName)) - throw new ArgumentException("typeName is null or empty"); - - // jump to line number if the decompiled view content exists - no need for a new decompilation - foreach (var viewContent in WorkbenchSingleton.Workbench.ViewContentCollection.OfType()) { - if (string.Equals(viewContent.AssemblyFile, assemblyFile, StringComparison.OrdinalIgnoreCase) && typeName == viewContent.FullTypeName) { - if (updateMarker) { - viewContent.UpdateDebuggingUI(); - } - if (lineNumber > 0) - viewContent.JumpToLineNumber(lineNumber); - else - viewContent.JumpToEntity(entityTag); - viewContent.WorkbenchWindow.SelectWindow(); - return true; - } - } - - // create a new decompiled view - var decompiledView = new DecompiledViewContent(assemblyFile, typeName, entityTag); - decompiledView.DecompilationFinished += delegate { - if (updateMarker) { - decompiledView.UpdateDebuggingUI(); - } - if (lineNumber > 0) - decompiledView.JumpToLineNumber(lineNumber); - else - decompiledView.JumpToEntity(entityTag); - }; - WorkbenchSingleton.Workbench.ShowView(decompiledView); - return true; - } - */ } } diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs deleted file mode 100644 index ed6d05eb7b..0000000000 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs +++ /dev/null @@ -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 -{ - /// - /// Equivalent to AE.AddIn CodeEditor, but without editing capabilities. - /// - 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(); - 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); - } - } -} diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs index 4d984527e9..287d0e57e6 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs @@ -3,14 +3,20 @@ using System; using System.Collections.Generic; +using System.ComponentModel.Design; using System.IO; +using System.Linq; using System.Threading; +using ICSharpCode.AvalonEdit.AddIn; +using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.Core; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Ast; +using ICSharpCode.Decompiler.Disassembler; +using ICSharpCode.NRefactory.Documentation; +using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.ILSpyAddIn.LaunchILSpy; -using ICSharpCode.ILSpyAddIn.ViewContent; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; @@ -24,11 +30,15 @@ namespace ICSharpCode.ILSpyAddIn /// /// Hosts a decompiled type. /// - class DecompiledViewContent : AbstractViewContentWithoutFile + class DecompiledViewContent : AbstractViewContentWithoutFile, IPositionable { readonly FileName assemblyFile; readonly string fullTypeName; - readonly FileName virtualFileName; + public FileName VirtualFileName { get; private set; } + + public override FileName PrimaryFileName { + get { return this.VirtualFileName; } + } /// /// Entity to jump to once decompilation has finished. @@ -37,16 +47,19 @@ namespace ICSharpCode.ILSpyAddIn bool decompilationFinished; - readonly CodeView codeView; + readonly CodeEditor codeEditor = new CodeEditor(); readonly CancellationTokenSource cancellation = new CancellationTokenSource(); Dictionary memberLocations; + public Dictionary DebugSymbols { get; private set; } #region Constructor public DecompiledViewContent(FileName assemblyFile, string fullTypeName, string entityTag) { - this.virtualFileName = FileName.Create("ilspy://" + assemblyFile + "/" + fullTypeName); - this.codeView = new CodeView(); + this.VirtualFileName = FileName.Create("ilspy://" + assemblyFile + "/" + fullTypeName + ".cs"); + + this.Services = codeEditor.PrimaryTextEditor.GetRequiredService(); + this.Services.AddService(typeof(IPositionable), this); this.assemblyFile = assemblyFile; this.fullTypeName = fullTypeName; @@ -55,15 +68,68 @@ namespace ICSharpCode.ILSpyAddIn string shortTypeName = fullTypeName.Substring(fullTypeName.LastIndexOf('.') + 1); this.TitleName = "[" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(shortTypeName) + "]"; - Thread thread = new Thread(DecompilationThread); - thread.Name = "Decompiler (" + shortTypeName + ")"; - thread.Start(); + DecompilationThread(); +// Thread thread = new Thread(DecompilationThread); +// thread.Name = "Decompiler (" + shortTypeName + ")"; +// thread.Start(); +// thread.Join(); SD.BookmarkManager.BookmarkRemoved += BookmarkManager_Removed; SD.BookmarkManager.BookmarkAdded += BookmarkManager_Added; + + this.codeEditor.FileName = this.VirtualFileName; + this.codeEditor.ActiveTextEditor.IsReadOnly = true; + this.codeEditor.ActiveTextEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#"); } #endregion + public static DecompiledViewContent Get(FileName virtualFileName) + { + var viewContents = SD.Workbench.ViewContentCollection.OfType(); + return viewContents.FirstOrDefault(c => c.VirtualFileName == virtualFileName); + } + + public static DecompiledViewContent Get(IEntity entity) + { + if (entity == null) + throw new ArgumentNullException("entity"); + + // Get the underlying entity for generic instance members + if (entity is IMember) + entity = ((IMember)entity).MemberDefinition; + + ITypeDefinition declaringType = (entity as ITypeDefinition) ?? entity.DeclaringTypeDefinition; + if (declaringType == null) + return null; + // get the top-level type + while (declaringType.DeclaringTypeDefinition != null) + declaringType = declaringType.DeclaringTypeDefinition; + + FileName assemblyLocation = declaringType.ParentAssembly.GetRuntimeAssemblyLocation(); + if (assemblyLocation != null && File.Exists(assemblyLocation)) { + return Get(assemblyLocation, declaringType.ReflectionName); + } + return null; + } + + public static DecompiledViewContent Get(FileName assemblyFile, string typeName) + { + if (assemblyFile == null) + throw new ArgumentNullException("assemblyFile"); + if (string.IsNullOrEmpty(typeName)) + throw new ArgumentException("typeName is null or empty"); + + foreach (var viewContent in SD.Workbench.ViewContentCollection.OfType()) { + if (viewContent.AssemblyFile == assemblyFile && typeName == viewContent.FullTypeName) { + return viewContent; + } + } + + var newViewContent = new DecompiledViewContent(assemblyFile, typeName, null); + SD.Workbench.ShowView(newViewContent); + return newViewContent; + } + #region Properties public FileName AssemblyFile { get { return assemblyFile; } @@ -77,7 +143,7 @@ namespace ICSharpCode.ILSpyAddIn } public override object Control { - get { return codeView; } + get { return codeEditor; } } public override bool IsReadOnly { @@ -90,7 +156,7 @@ namespace ICSharpCode.ILSpyAddIn public override void Dispose() { cancellation.Cancel(); - codeView.Dispose(); + codeEditor.Dispose(); SD.BookmarkManager.BookmarkAdded -= BookmarkManager_Added; SD.BookmarkManager.BookmarkRemoved -= BookmarkManager_Removed; // DecompileInformation data; @@ -112,7 +178,7 @@ namespace ICSharpCode.ILSpyAddIn // TODO: show Save As dialog to allow the user to save the decompiled file } #endregion - + #region JumpToEntity public void JumpToEntity(string entityIdString) { @@ -121,8 +187,8 @@ namespace ICSharpCode.ILSpyAddIn return; } TextLocation location; - if (memberLocations != null && memberLocations.TryGetValue(entityIdString, out location)) - codeView.JumpTo(location.Line, location.Column); + if (entityIdString != null && memberLocations != null && memberLocations.TryGetValue(entityIdString, out location)) + this.JumpTo(location.Line, location.Column); } #endregion @@ -132,9 +198,10 @@ namespace ICSharpCode.ILSpyAddIn try { StringWriter writer = new StringWriter(); RunDecompiler(assemblyFile, fullTypeName, new DebuggerTextOutput(new PlainTextOutput(writer)), cancellation.Token); - if (!cancellation.IsCancellationRequested) { - SD.MainThread.InvokeAsyncAndForget(() => OnDecompilationFinished(writer)); - } +// if (!cancellation.IsCancellationRequested) { +// SD.MainThread.InvokeAsyncAndForget(() => OnDecompilationFinished(writer)); +// } + OnDecompilationFinished(writer); } catch (OperationCanceledException) { // ignore cancellation } catch (Exception ex) { @@ -169,16 +236,20 @@ namespace ICSharpCode.ILSpyAddIn astBuilder.AddType(typeDefinition); astBuilder.GenerateCode(textOutput); + // ReflectionDisassembler disasm = new ReflectionDisassembler(textOutput, true, cancellationToken); + // disasm.DisassembleType(typeDefinition); + // save decompilation data memberLocations = textOutput.MemberLocations; + this.DebugSymbols = textOutput.DebugSymbols; } void OnDecompilationFinished(StringWriter output) { if (cancellation.IsCancellationRequested) return; - codeView.Document.Text = output.ToString(); - codeView.Document.UndoStack.ClearAll(); + codeEditor.Document.Text = output.ToString(); + codeEditor.Document.UndoStack.ClearAll(); this.decompilationFinished = true; JumpToEntity(this.jumpToEntityIdStringWhenDecompilationFinished); @@ -205,65 +276,15 @@ namespace ICSharpCode.ILSpyAddIn codeView.IconBarManager.Bookmarks.Add(bookmark); } } - - public void UpdateDebuggingUI() - { - if (!DebuggerService.IsDebuggerStarted) - return; - if (decompiledType == null || decompiledType.MetadataToken == null) - return; - - int typeToken = decompiledType.MetadataToken.ToInt32(); - if (!DebuggerDecompilerService.DebugInformation.ContainsKey(typeToken)) - return; - var decompilerService = DebuggerDecompilerService.Instance; - if (decompilerService == null || decompilerService.DebugStepInformation == null) - return; - - // get debugging information - DecompileInformation debugInformation = (DecompileInformation)DebuggerDecompilerService.DebugInformation[typeToken]; - int methodToken = decompilerService.DebugStepInformation.Item1; - int ilOffset = decompilerService.DebugStepInformation.Item2; - int line; - MemberReference member; - if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(methodToken)) - return; - - debugInformation.CodeMappings[methodToken].GetInstructionByTokenAndOffset(methodToken, ilOffset, out member, out line); - - // if the codemappings are not built - if (line <= 0) { - DebuggerService.CurrentDebugger.StepOver(); - return; - } - - // jump to line - scoll and unfold - this.UpdateCurrentLineBookmark(line); - this.JumpToLineNumber(line); - } - - void UpdateCurrentLineBookmark(int lineNumber) - { - if (lineNumber <= 0) - return; - - CurrentLineBookmark.SetPosition(uri, codeView.Document, lineNumber, 0, lineNumber, 0); - var currentLineBookmark = BookmarkManager.Bookmarks.OfType().FirstOrDefault(); - if (currentLineBookmark != null) { - // update bookmark & marker - codeView.IconBarManager.Bookmarks.Add(currentLineBookmark); - currentLineBookmark.Document = this.codeView.TextEditor.Document; - } - }*/ - + */ #endregion #region Bookmarks void BookmarkManager_Removed(object sender, BookmarkEventArgs e) { var mark = e.Bookmark; - if (mark != null && codeView.IconBarManager.Bookmarks.Contains(mark)) { - codeView.IconBarManager.Bookmarks.Remove(mark); + if (mark != null && codeEditor.IconBarManager.Bookmarks.Contains(mark)) { + codeEditor.IconBarManager.Bookmarks.Remove(mark); mark.Document = null; } } @@ -271,13 +292,28 @@ namespace ICSharpCode.ILSpyAddIn void BookmarkManager_Added(object sender, BookmarkEventArgs e) { var mark = e.Bookmark; - if (mark != null && mark is BreakpointBookmark && mark.FileName == virtualFileName) { - codeView.IconBarManager.Bookmarks.Add(mark); - mark.Document = this.codeView.Document; + if (mark != null && mark.FileName == VirtualFileName) { + codeEditor.IconBarManager.Bookmarks.Add(mark); + mark.Document = this.codeEditor.Document; } } #endregion + #region IPositionable + public int Line { + get { return codeEditor.ActiveTextEditorAdapter.Caret.Line; } + } + + public int Column { + get { return codeEditor.ActiveTextEditorAdapter.Caret.Column; } + } + + public void JumpTo(int line, int column) + { + codeEditor.ActiveTextEditor.JumpTo(line, column); + } + #endregion + #region Events public event EventHandler DecompilationFinished; diff --git a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsEditor.csproj b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsEditor.csproj index 06e332f6ca..7e454a0b84 100644 --- a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsEditor.csproj +++ b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsEditor.csproj @@ -46,7 +46,6 @@ - 4.0 @@ -70,19 +69,12 @@ - - SettingsView.cs - - - - SettingsView.cs - - - SettingsViewXaml.xaml + + SettingsView.xaml Code @@ -111,7 +103,7 @@ - + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.Designer.cs b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.Designer.cs deleted file mode 100644 index e1ad3b4d7c..0000000000 --- a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.Designer.cs +++ /dev/null @@ -1,121 +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) - -namespace ICSharpCode.SettingsEditor -{ - partial class SettingsView - { - /// - /// Designer variable used to keep track of non-visual components. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Disposes resources used by the control. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing) { - if (components != null) { - components.Dispose(); - } - } - base.Dispose(disposing); - } - - /// - /// This method is required for Windows Forms designer support. - /// Do not change the method contents inside the source code editor. The Forms designer might - /// not be able to load this method if it was changed manually. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.grid = new System.Windows.Forms.DataGridView(); - this.NameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.TypeColumn = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.ScopeColumn = new System.Windows.Forms.DataGridViewComboBoxColumn(); - this.ValueColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.bindingSource = new System.Windows.Forms.BindingSource(this.components); - ((System.ComponentModel.ISupportInitialize)(this.grid)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).BeginInit(); - this.SuspendLayout(); - // - // grid - // - this.grid.AutoGenerateColumns = false; - this.grid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.grid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.NameColumn, - this.TypeColumn, - this.ScopeColumn, - this.ValueColumn}); - this.grid.DataSource = this.bindingSource; - this.grid.Dock = System.Windows.Forms.DockStyle.Fill; - this.grid.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystroke; - this.grid.Location = new System.Drawing.Point(0, 0); - this.grid.Name = "grid"; - this.grid.Size = new System.Drawing.Size(486, 362); - this.grid.TabIndex = 0; - this.grid.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.GridDataError); - this.grid.SelectionChanged += new System.EventHandler(this.GridSelectionChanged); - this.grid.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.GridUserDeletingRow); - // - // NameColumn - // - this.NameColumn.DataPropertyName = "Name"; - this.NameColumn.HeaderText = "Name"; - this.NameColumn.MinimumWidth = 50; - this.NameColumn.Name = "NameColumn"; - // - // TypeColumn - // - this.TypeColumn.DataPropertyName = "WrappedSettingType"; - this.TypeColumn.DropDownWidth = 255; - this.TypeColumn.HeaderText = "Type"; - this.TypeColumn.MinimumWidth = 50; - this.TypeColumn.Name = "TypeColumn"; - this.TypeColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - // - // ScopeColumn - // - this.ScopeColumn.DataPropertyName = "Scope"; - this.ScopeColumn.DropDownWidth = 80; - this.ScopeColumn.HeaderText = "Scope"; - this.ScopeColumn.MinimumWidth = 30; - this.ScopeColumn.Name = "ScopeColumn"; - this.ScopeColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - // - // ValueColumn - // - this.ValueColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.ValueColumn.DataPropertyName = "SerializedValue"; - this.ValueColumn.HeaderText = "Value"; - this.ValueColumn.MinimumWidth = 50; - this.ValueColumn.Name = "ValueColumn"; - // - // bindingSource - // - this.bindingSource.DataSource = typeof(ICSharpCode.SettingsEditor.SettingsEntry); - this.bindingSource.AddingNew += new System.ComponentModel.AddingNewEventHandler(this.BindingSourceAddingNew); - // - // SettingsView - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.grid); - this.Name = "SettingsView"; - this.Size = new System.Drawing.Size(486, 362); - ((System.ComponentModel.ISupportInitialize)(this.grid)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).EndInit(); - this.ResumeLayout(false); - } - private System.Windows.Forms.DataGridViewComboBoxColumn TypeColumn; - private System.Windows.Forms.DataGridViewComboBoxColumn ScopeColumn; - private System.Windows.Forms.DataGridViewTextBoxColumn ValueColumn; - private System.Windows.Forms.DataGridViewTextBoxColumn NameColumn; - private System.Windows.Forms.BindingSource bindingSource; - private System.Windows.Forms.DataGridView grid; - } -} diff --git a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.cs b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.cs deleted file mode 100644 index fed206380a..0000000000 --- a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.cs +++ /dev/null @@ -1,181 +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.ComponentModel; -using System.Drawing; -using System.Windows.Forms; -using System.Collections.Generic; -using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.TypeSystem.Implementation; -using ICSharpCode.SharpDevelop.Gui; -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop; - -namespace ICSharpCode.SettingsEditor -{ - public partial class SettingsView : UserControl, ISettingsEntryHost - { - public event EventHandler SelectionChanged; - public event EventHandler SettingsChanged; - - static readonly Type[] defaultAvailableTypes = new Type[] { - typeof(bool), - typeof(byte), - typeof(char), - typeof(decimal), - typeof(double), - typeof(float), - typeof(int), - typeof(long), - typeof(sbyte), - typeof(short), - typeof(string), - typeof(System.Collections.Specialized.StringCollection), - typeof(System.DateTime), - typeof(System.Drawing.Color), - typeof(System.Drawing.Font), - typeof(System.Drawing.Point), - typeof(System.Drawing.Size), - typeof(System.Guid), - typeof(System.TimeSpan), - typeof(uint), - typeof(ulong), - typeof(ushort) - }; - - List typeNames = new List(); - List types = new List(); - IAmbience ambience; - ICompilation compilation; - - public SettingsView() - { - InitializeComponent(); - - ambience = AmbienceService.GetCurrentAmbience(); - compilation = MinimalCorlib.Instance.CreateCompilation(); - - foreach (Type type in defaultAvailableTypes) { - types.Add(type); - typeNames.Add(ambience.ConvertType(type.ToTypeReference().Resolve(compilation))); - } - foreach (SpecialTypeDescriptor d in SpecialTypeDescriptor.Descriptors) { - types.Add(d.type); - typeNames.Add(d.name); - } - - ScopeColumn.DataSource = Enum.GetValues(typeof(SettingScope)); - TypeColumn.DataSource = typeNames; - } - - public void ShowEntries(IList list) - { - bindingSource.Clear(); - foreach (SettingsEntry entry in list) { - bindingSource.Add(entry); - } - bindingSource.ListChanged += delegate(object sender, ListChangedEventArgs e) { - if (e.NewIndex >= 0 && e.NewIndex < bindingSource.Count) { - if (((SettingsEntry)bindingSource[e.NewIndex]).Name != null) { - OnSettingsChanged(e); - } - } - }; - } - - void GridSelectionChanged(object sender, EventArgs e) - { - if (SelectionChanged != null) - SelectionChanged(this, e); - } - - public IEnumerable GetAllEntries() - { - List l = new List(); - foreach (SettingsEntry entry in bindingSource) { - if (!string.IsNullOrEmpty(entry.Name)) { - l.Add(entry); - } - } - l.Sort(delegate(SettingsEntry a, SettingsEntry b) { - return a.Name.CompareTo(b.Name); - }); - return l; - } - - public List GetSelectedEntriesForPropertyGrid() - { - List l - = new List(); - if (grid.SelectedRows.Count > 0) { - foreach (DataGridViewRow row in grid.SelectedRows) { - if (row.DataBoundItem != null) { - l.Add(new SettingsEntryPropertyGridWrapper((SettingsEntry)row.DataBoundItem)); - } - } - } else { - bool[] rowAdded = new bool[grid.Rows.Count]; - foreach (DataGridViewCell cell in grid.SelectedCells) { - if (rowAdded[cell.RowIndex] == false) { - rowAdded[cell.RowIndex] = true; - if (cell.OwningRow.DataBoundItem != null) { - l.Add(new SettingsEntryPropertyGridWrapper((SettingsEntry)cell.OwningRow.DataBoundItem)); - } - } - } - } - return l; - } - - void BindingSourceAddingNew(object sender, AddingNewEventArgs e) - { - SettingsEntry entry = new SettingsEntry(this); - entry.Type = typeof(string); - e.NewObject = entry; - } - - void GridDataError(object sender, DataGridViewDataErrorEventArgs e) - { - LoggingService.Debug("Row " + e.RowIndex + ", column " + e.ColumnIndex + ", error " + e.Exception.ToString()); - if (e.Exception != null) { - MessageBox.Show("Error in data entry: " + e.Exception.Message); - } else { - MessageBox.Show("Error in data entry"); - } - } - - string ISettingsEntryHost.GetDisplayNameForType(Type type) - { - foreach (SpecialTypeDescriptor d in SpecialTypeDescriptor.Descriptors) { - if (type == d.type) - return d.name; - } - return ambience.ConvertType(type.ToTypeReference().Resolve(compilation)); - } - - Type ISettingsEntryHost.GetTypeByDisplayName(string displayName) - { - for (int i = 0; i < typeNames.Count; i++) { - if (typeNames[i] == displayName) - return types[i]; - } - return null; - } - - void GridUserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) - { - if (e.Row != null && !e.Cancel) { - OnSettingsChanged(EventArgs.Empty); - } - } - - protected virtual void OnSettingsChanged(EventArgs e) - { - if (SettingsChanged != null) { - SettingsChanged(this, e); - } - } - } -} diff --git a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.resx b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.resx deleted file mode 100644 index 186f9f6019..0000000000 --- a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.resx +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 28, 18 - - \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsViewXaml.xaml b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.xaml similarity index 97% rename from src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsViewXaml.xaml rename to src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.xaml index d107534e3f..a85631658b 100644 --- a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsViewXaml.xaml +++ b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsView.xaml @@ -1,6 +1,6 @@ /// Interaction logic for SettingsViewXaml.xaml /// - public partial class SettingsViewXaml : UserControl,ISettingsEntryHost + public partial class SettingsView : UserControl,ISettingsEntryHost { public event EventHandler SettingsChanged; public event EventHandler SelectionChanged; @@ -65,7 +58,7 @@ namespace ICSharpCode.SettingsEditor IAmbience ambience; ICompilation compilation; - public SettingsViewXaml() + public SettingsView() { InitializeComponent(); diff --git a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsViewContent.cs b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsViewContent.cs index 09c58d15c1..3b64f09f69 100644 --- a/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsViewContent.cs +++ b/src/AddIns/DisplayBindings/SettingsEditor/Project/SettingsViewContent.cs @@ -19,8 +19,7 @@ namespace ICSharpCode.SettingsEditor { public class SettingsViewContent : AbstractViewContentHandlingLoadErrors, IHasPropertyContainer { -// SettingsView view = new SettingsView(); - SettingsViewXaml view = new SettingsViewXaml(); + SettingsView view = new SettingsView(); PropertyContainer propertyContainer = new PropertyContainer(); SettingsDocument setDoc = new SettingsDocument(); MemoryStream appConfigStream; @@ -29,30 +28,17 @@ namespace ICSharpCode.SettingsEditor public SettingsViewContent(OpenedFile file) : base(file) { TryOpenAppConfig(false); - /* - view.SelectionChanged += delegate { - propertyContainer.SelectedObjects = view.GetSelectedEntriesForPropertyGrid().ToArray(); - }; - view.SettingsChanged += delegate { - if (this.PrimaryFile != null) - this.PrimaryFile.MakeDirty(); - if (appConfigFile != null) - appConfigFile.MakeDirty(); - }; - */ - + this.UserContent = view; view.SelectionChanged += ((s,e) => { - Console.WriteLine("SettingsViewContent.SelectionChanged"); propertyContainer.SelectedObjects = view.GetSelectedEntriesForPropertyGrid().ToArray(); }); view.SettingsChanged += ((s,e) => { - Console.WriteLine("SettingsViewContent.SettingsChanged"); if (this.PrimaryFile != null) this.PrimaryFile.MakeDirty(); if (appConfigFile != null) @@ -61,6 +47,7 @@ namespace ICSharpCode.SettingsEditor } + void TryOpenAppConfig(bool createIfNotExists) { if (appConfigFile != null) // already open @@ -80,6 +67,7 @@ namespace ICSharpCode.SettingsEditor } } + protected override void LoadInternal(OpenedFile file, Stream stream) { Console.WriteLine ("LoadInternal"); @@ -101,6 +89,7 @@ namespace ICSharpCode.SettingsEditor } + void ShowLoadError(string message) { MessageService.ShowMessage(message); diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index 3437af546b..fae41f6860 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -126,7 +126,7 @@ namespace ICSharpCode.Decompiler.Ast astBlock.Statements.InsertBefore(insertionPoint, newVarDecl); } - astBlock.AddAnnotation(new MemberMapping(methodDef) { LocalVariables = localVariables }); + astBlock.AddAnnotation(new MethodDebugSymbols(methodDef) { LocalVariables = localVariables.ToList() }); return astBlock; } @@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.Ast if (node is ILLabel) { yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name }; } else if (node is ILExpression) { - List ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); + List ilRanges = ILRange.OrderAndJoin(node.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); AstNode codeExpr = TransformExpression((ILExpression)node); if (codeExpr != null) { codeExpr = codeExpr.WithAnnotation(ilRanges); @@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.Ast Expression astExpr = node as Expression; // get IL ranges - used in debugger - List ilRanges = ILRange.OrderAndJoint(expr.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); + List ilRanges = ILRange.OrderAndJoin(expr.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); AstNode result; if (astExpr != null) diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs index c43b0c7c25..613ac1c582 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs @@ -36,6 +36,8 @@ namespace ICSharpCode.Decompiler.Ast bool firstUsingDeclaration; bool lastUsingDeclaration; + TextLocation? lastEndOfLine; + public bool FoldBraces = false; public TextOutputFormatter(ITextOutput output) @@ -217,6 +219,7 @@ namespace ICSharpCode.Decompiler.Ast output.MarkFoldEnd(); lastUsingDeclaration = false; } + lastEndOfLine = output.Location; output.WriteLine(); } @@ -265,8 +268,7 @@ namespace ICSharpCode.Decompiler.Ast } Stack startLocations = new Stack(); - MemberMapping currentMemberMapping; - Stack parentMemberMappings = new Stack(); + Stack symbolsStack = new Stack(); public void StartNode(AstNode node) { @@ -284,11 +286,10 @@ namespace ICSharpCode.Decompiler.Ast if (node is EntityDeclaration && node.Annotation() != null && node.GetChildByRole(Roles.Identifier).IsNull) output.WriteDefinition("", node.Annotation(), false); - - MemberMapping mapping = node.Annotation(); - if (mapping != null) { - parentMemberMappings.Push(currentMemberMapping); - currentMemberMapping = mapping; + + if (node.Annotation() != null) { + symbolsStack.Push(node.Annotation()); + symbolsStack.Peek().StartLocation = startLocations.Peek(); } } @@ -305,26 +306,21 @@ namespace ICSharpCode.Decompiler.Ast var startLocation = startLocations.Pop(); // code mappings - if (currentMemberMapping != null) { - var ranges = node.Annotation>(); - if (ranges != null && ranges.Count > 0) { - // add all ranges - foreach (var range in ranges) { - currentMemberMapping.MemberCodeMappings.Add( - new SourceCodeMapping { - ILInstructionOffset = range, - StartLocation = startLocation, - EndLocation = output.Location, - MemberMapping = currentMemberMapping - }); - } - } + var ranges = node.Annotation>(); + if (symbolsStack.Count > 0 && ranges != null && ranges.Count > 0) { + // Ignore the newline which was printed at the end of the statement + TextLocation endLocation = (node is Statement) ? (lastEndOfLine ?? output.Location) : output.Location; + symbolsStack.Peek().SequencePoints.Add( + new SequencePoint() { + ILRanges = ILRange.OrderAndJoin(ranges).ToArray(), + StartLocation = startLocation, + EndLocation = endLocation + }); } - - if (node.Annotation() != null) { - output.AddDebuggerMemberMapping(currentMemberMapping); - currentMemberMapping = parentMemberMappings.Pop(); + if (node.Annotation() != null) { + symbolsStack.Peek().EndLocation = output.Location; + output.AddDebugSymbols(symbolsStack.Pop()); } } diff --git a/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs b/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs index 3fef8970b4..b2dcab8621 100644 --- a/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs +++ b/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs @@ -17,240 +17,41 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using ICSharpCode.Decompiler.Ast; -using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.ILAst; using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.CSharp; using Mono.Cecil; namespace ICSharpCode.Decompiler { - /// - /// Maps the source code to IL. - /// - public sealed class SourceCodeMapping + /// Maps method's source code to IL + public class MethodDebugSymbols { - /// - /// Gets or sets the start location of the instruction. - /// + public MethodDefinition CecilMethod { get; set; } + public List LocalVariables { get; set; } + public List SequencePoints { get; set; } public TextLocation StartLocation { get; set; } - - /// - /// Gets or sets the end location of the instruction. - /// public TextLocation EndLocation { get; set; } - /// - /// Gets or sets IL Range offset for the source code line. E.g.: 13-19 <-> 135. - /// - public ILRange ILInstructionOffset { get; set; } - - /// - /// Gets or sets the member mapping this source code mapping belongs to. - /// - public MemberMapping MemberMapping { get; set; } - - /// - /// Retrieves the array that contains the IL range and the missing gaps between ranges. - /// - /// The array representation of the step aranges. - public int[] ToArray(bool isMatch) - { - var currentList = new List(); - - // add list for the current source code line - currentList.AddRange(ILRange.OrderAndJoint(MemberMapping.MemberCodeMappings - .FindAll(m => m.StartLocation.Line == this.StartLocation.Line) - .ConvertAll(m => m.ILInstructionOffset))); - - if (!isMatch) { - // add inverted - currentList.AddRange(MemberMapping.InvertedList); - } else { - // if the current list contains the last mapping, add also the last gap - var lastInverted = MemberMapping.InvertedList.LastOrDefault(); - if (lastInverted != null && lastInverted.From == currentList[currentList.Count - 1].To) - currentList.Add(lastInverted); - } - - // set the output - var resultList = new List(); - foreach (var element in ILRange.OrderAndJoint(currentList)) { - resultList.Add(element.From); - resultList.Add(element.To); - } - - return resultList.ToArray(); - } - } - - /// - /// Stores the member information and its source code mappings. - /// - public sealed class MemberMapping - { - IEnumerable invertedList; - - internal MemberMapping() - { - } - - public MemberMapping(MethodDefinition method) - { - this.MetadataToken = method.MetadataToken.ToInt32(); - this.MemberCodeMappings = new List(); - this.MemberReference = method; - this.CodeSize = method.Body.CodeSize; - } - - /// - /// Gets or sets the type of the mapping. - /// - public MemberReference MemberReference { get; internal set; } - - /// - /// Metadata token of the member. - /// - public int MetadataToken { get; internal set; } - - /// - /// Gets or sets the code size for the member mapping. - /// - public int CodeSize { get; internal set; } - - /// - /// Gets or sets the source code mappings. - /// - public List MemberCodeMappings { get; internal set; } - - /// - /// Gets or sets the local variables. - /// - public IEnumerable LocalVariables { get; internal set; } - - /// - /// Gets the inverted IL Ranges.
- /// E.g.: for (0-9, 11-14, 14-18, 21-25) => (9-11,18-21). - ///
- /// IL Range inverted list. - public IEnumerable InvertedList + public MethodDebugSymbols(MethodDefinition methodDef) { - get { - if (invertedList == null) { - var list = MemberCodeMappings.ConvertAll( - s => new ILRange { From = s.ILInstructionOffset.From, To = s.ILInstructionOffset.To }); - invertedList = ILRange.OrderAndJoint(ILRange.Invert(list, CodeSize)); - } - return invertedList; - } + this.CecilMethod = methodDef; + this.LocalVariables = new List(); + this.SequencePoints = new List(); } } - /// - /// Code mappings helper class. - /// - public static class CodeMappings + public class SequencePoint { - /// - /// Gets source code mapping and metadata token based on type name and line number. - /// - /// Code mappings storage. - /// Member reference name. - /// Line number. - /// Metadata token. - /// - public static SourceCodeMapping GetInstructionByLineNumber( - this MemberMapping codeMapping, - int lineNumber, - out int metadataToken) - { - if (codeMapping == null) - throw new ArgumentException("CodeMappings storage must be valid!"); - - var map = codeMapping.MemberCodeMappings.Find(m => m.StartLocation.Line == lineNumber); - if (map != null) { - metadataToken = codeMapping.MetadataToken; - return map; - } - - metadataToken = 0; - return null; - } - - /// - /// Gets a mapping given a type, a token and an IL offset. - /// - /// Code mappings storage. - /// Token. - /// IL offset. - /// True, if perfect match. - /// A code mapping. - public static SourceCodeMapping GetInstructionByTokenAndOffset( - this MemberMapping codeMapping, - int ilOffset, - out bool isMatch) - { - isMatch = false; - - if (codeMapping == null) - throw new ArgumentNullException("CodeMappings storage must be valid!"); - - // try find an exact match - var map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To); - - if (map == null) { - // get the immediate next one - map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From > ilOffset); - isMatch = false; - if (map == null) - map = codeMapping.MemberCodeMappings.LastOrDefault(); // get the last - - return map; - } - - isMatch = true; - return map; - } + public ILRange[] ILRanges { get; set; } + public TextLocation StartLocation { get; set; } + public TextLocation EndLocation { get; set; } + public int ILOffset { get { return this.ILRanges[0].From; } } - /// - /// Gets the source code and type name from metadata token and offset. - /// - /// Code mapping storage. - /// Metadata token. - /// IL offset. - /// Type definition. - /// Line number. - /// It is possible to exist to different types from different assemblies with the same metadata token. - public static bool GetInstructionByTokenAndOffset( - this MemberMapping mapping, - int ilOffset, - out MemberReference member, - out int line) + public override string ToString() { - member = null; - line = 0; - - if (mapping == null) - throw new ArgumentException("CodeMappings storage must be valid!"); - - var codeMapping = mapping.MemberCodeMappings.Find( - cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1); - if (codeMapping == null) { - codeMapping = mapping.MemberCodeMappings.Find(cm => cm.ILInstructionOffset.From > ilOffset); - if (codeMapping == null) { - codeMapping = mapping.MemberCodeMappings.LastOrDefault(); - if (codeMapping == null) - return false; - } - } - - member = mapping.MemberReference; - line = codeMapping.StartLocation.Line; - return true; + return string.Join(" ", this.ILRanges) + " " + this.StartLocation + "-" + this.EndLocation; } } } diff --git a/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index 04abfe5118..a45a718207 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.Disassembler this.cancellationToken = cancellationToken; } - public void Disassemble(MethodBody body, MemberMapping methodMapping) + public void Disassemble(MethodBody body, MethodDebugSymbols debugSymbols) { // start writing IL code MethodDefinition method = body.Method; @@ -82,20 +82,19 @@ namespace ICSharpCode.Decompiler.Disassembler if (detectControlStructure && body.Instructions.Count > 0) { Instruction inst = body.Instructions[0]; HashSet branchTargets = GetBranchTargets(body.Instructions); - WriteStructureBody(new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize); + WriteStructureBody(new ILStructure(body), branchTargets, ref inst, debugSymbols, method.Body.CodeSize); } else { foreach (var inst in method.Body.Instructions) { var startLocation = output.Location; inst.WriteTo(output); - if (methodMapping != null) { + if (debugSymbols != null) { // add IL code mappings - used in debugger - methodMapping.MemberCodeMappings.Add( - new SourceCodeMapping() { + debugSymbols.SequencePoints.Add( + new SequencePoint() { StartLocation = output.Location, EndLocation = output.Location, - ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset }, - MemberMapping = methodMapping + ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) } }); } @@ -174,7 +173,7 @@ namespace ICSharpCode.Decompiler.Disassembler output.Indent(); } - void WriteStructureBody(ILStructure s, HashSet branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize) + void WriteStructureBody(ILStructure s, HashSet branchTargets, ref Instruction inst, MethodDebugSymbols debugSymbols, int codeSize) { bool isFirstInstructionInStructure = true; bool prevInstructionWasBranch = false; @@ -184,7 +183,7 @@ namespace ICSharpCode.Decompiler.Disassembler if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) { ILStructure child = s.Children[childIndex++]; WriteStructureHeader(child); - WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize); + WriteStructureBody(child, branchTargets, ref inst, debugSymbols, codeSize); WriteStructureFooter(child); } else { if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) { @@ -194,13 +193,12 @@ namespace ICSharpCode.Decompiler.Disassembler inst.WriteTo(output); // add IL code mappings - used in debugger - if (currentMethodMapping != null) { - currentMethodMapping.MemberCodeMappings.Add( - new SourceCodeMapping() { + if (debugSymbols != null) { + debugSymbols.SequencePoints.Add( + new SequencePoint() { StartLocation = startLocation, EndLocation = output.Location, - ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset }, - MemberMapping = currentMethodMapping + ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) } }); } diff --git a/src/Libraries/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/src/Libraries/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index ed246a092a..ec20cfa72a 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -22,6 +22,7 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; +using ICSharpCode.NRefactory; using Mono.Cecil; using Mono.Collections.Generic; @@ -114,6 +115,8 @@ namespace ICSharpCode.Decompiler.Disassembler // instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed // + TextLocation startLocation = output.Location; + //emit flags WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility); WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags); @@ -217,9 +220,11 @@ namespace ICSharpCode.Decompiler.Disassembler if (method.HasBody) { // create IL code mappings - used in debugger - MemberMapping methodMapping = new MemberMapping(method); - methodBodyDisassembler.Disassemble(method.Body, methodMapping); - output.AddDebuggerMemberMapping(methodMapping); + MethodDebugSymbols debugSymbols = new MethodDebugSymbols(method); + debugSymbols.StartLocation = startLocation; + methodBodyDisassembler.Disassemble(method.Body, debugSymbols); + debugSymbols.EndLocation = output.Location; + output.AddDebugSymbols(debugSymbols); } CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name)); diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs index cbdc5d771f..da8c6c6beb 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs @@ -743,7 +743,7 @@ namespace ICSharpCode.Decompiler.ILAst // Convert stack-based IL code to ILAst tree foreach(ByteCode byteCode in body) { - ILRange ilRange = new ILRange() { From = byteCode.Offset, To = byteCode.EndOffset }; + ILRange ilRange = new ILRange(byteCode.Offset, byteCode.EndOffset); if (byteCode.StackBefore == null) { // Unreachable code diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs index 4f3930fcdd..9cd42a14fc 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs @@ -221,37 +221,43 @@ namespace ICSharpCode.Decompiler.ILAst } } - public class ILRange + public struct ILRange { - public int From; - public int To; // Exlusive + public readonly int From; + public readonly int To; // Exlusive + + public ILRange(int @from, int to) + { + this.From = @from; + this.To = to; + } public override string ToString() { - return string.Format("{0}-{1}", From.ToString("X"), To.ToString("X")); + return string.Format("{0:X2}-{1:X2}", From, To); } - public static List OrderAndJoint(IEnumerable input) + public static List OrderAndJoin(IEnumerable input) { if (input == null) throw new ArgumentNullException("Input is null!"); - List ranges = input.Where(r => r != null).OrderBy(r => r.From).ToList(); - for (int i = 0; i < ranges.Count - 1;) { - ILRange curr = ranges[i]; - ILRange next = ranges[i + 1]; - // Merge consequtive ranges if they intersect - if (curr.From <= next.From && next.From <= curr.To) { - curr.To = Math.Max(curr.To, next.To); - ranges.RemoveAt(i + 1); - } else { - i++; + List result = new List(); + foreach(ILRange curr in input.OrderBy(r => r.From)) { + if (result.Count > 0) { + // Merge consequtive ranges if possible + ILRange last = result[result.Count - 1]; + if (curr.From <= last.To) { + result[result.Count - 1] = new ILRange(last.From, Math.Max(last.To, curr.To)); + continue; + } } + result.Add(curr); } - return ranges; + return result; } - public static IEnumerable Invert(IEnumerable input, int codeSize) + public static List Invert(IEnumerable input, int codeSize) { if (input == null) throw new ArgumentNullException("Input is null!"); @@ -259,23 +265,25 @@ namespace ICSharpCode.Decompiler.ILAst if (codeSize <= 0) throw new ArgumentException("Code size must be grater than 0"); - var ordered = OrderAndJoint(input); + List ordered = OrderAndJoin(input); + List result = new List(ordered.Count + 1); if (ordered.Count == 0) { - yield return new ILRange() { From = 0, To = codeSize }; + result.Add(new ILRange(0, codeSize)); } else { // Gap before the first element if (ordered.First().From != 0) - yield return new ILRange() { From = 0, To = ordered.First().From }; + result.Add(new ILRange(0, ordered.First().From)); // Gaps between elements for (int i = 0; i < ordered.Count - 1; i++) - yield return new ILRange() { From = ordered[i].To, To = ordered[i + 1].From }; + result.Add(new ILRange(ordered[i].To, ordered[i + 1].From)); // Gap after the last element Debug.Assert(ordered.Last().To <= codeSize); if (ordered.Last().To != codeSize) - yield return new ILRange() { From = ordered.Last().To, To = codeSize }; + result.Add(new ILRange(ordered.Last().To, codeSize)); } + return result; } } diff --git a/src/Libraries/ICSharpCode.Decompiler/ITextOutput.cs b/src/Libraries/ICSharpCode.Decompiler/ITextOutput.cs index 0bcf5eac6b..f13a55d61b 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ITextOutput.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ITextOutput.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler void WriteDefinition(string text, object definition, bool isLocal = true); void WriteReference(string text, object reference, bool isLocal = false); - void AddDebuggerMemberMapping(MemberMapping memberMapping); + void AddDebugSymbols(MethodDebugSymbols methodDebugSymbols); void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false); void MarkFoldEnd(); diff --git a/src/Libraries/ICSharpCode.Decompiler/PlainTextOutput.cs b/src/Libraries/ICSharpCode.Decompiler/PlainTextOutput.cs index f2d709cdd5..6319226d16 100644 --- a/src/Libraries/ICSharpCode.Decompiler/PlainTextOutput.cs +++ b/src/Libraries/ICSharpCode.Decompiler/PlainTextOutput.cs @@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler { } - void ITextOutput.AddDebuggerMemberMapping(MemberMapping memberMapping) + void ITextOutput.AddDebugSymbols(MethodDebugSymbols methodDebugSymbols) { } } diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs index 639a5d6c90..87f7e854b5 100644 --- a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs +++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs @@ -1786,11 +1786,6 @@ namespace ICSharpCode.NRefactory.TypeSystem set { throw new NotSupportedException(); } } - public override string FullName { - // This works because LazyCecilTypeDefinition is only used for top-level types - get { return cecilTypeDef.FullName; } - } - public override string ReflectionName { get { return cecilTypeDef.FullName; } } diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index fd31530a24..ae7eb45e0a 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -515,7 +515,6 @@ - diff --git a/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs b/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs index c425b17924..24ecebad61 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs @@ -52,9 +52,6 @@ namespace ICSharpCode.SharpDevelop.Debugging if (startColumn < 1) startColumn = 1; - IDocumentLine line = document.GetLineByNumber(startLine); - if (endColumn < 1 || endColumn > line.Length) - endColumn = line.Length; instance = new CurrentLineBookmark(); instance.Location = new TextLocation(startLine, startColumn); instance.FileName = fileName; @@ -96,8 +93,11 @@ namespace ICSharpCode.SharpDevelop.Debugging protected override ITextMarker CreateMarker(ITextMarkerService markerService) { - IDocumentLine line = this.Document.GetLineByNumber(startLine); - ITextMarker marker = markerService.Create(line.Offset + startColumn - 1, Math.Max(endColumn - startColumn, 1)); + IDocumentLine sLine = this.Document.GetLineByNumber(startLine); + IDocumentLine eLine = this.Document.GetLineByNumber(endLine); + int sOffset = Math.Min(sLine.Offset + startColumn - 1, sLine.EndOffset); + int eOffset = Math.Min(eLine.Offset + endColumn - 1, eLine.EndOffset); + ITextMarker marker = markerService.Create(sOffset, Math.Max(eOffset - sOffset, 1)); IHighlighter highlighter = this.Document.GetService(typeof(IHighlighter)) as IHighlighter; marker.BackgroundColor = DefaultBackground; marker.ForegroundColor = DefaultForeground; diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index a129f159b2..ec8705a596 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -231,55 +231,4 @@ namespace ICSharpCode.SharpDevelop.Debugging DebuggerService.CurrentDebugger.HandleToolTipRequest(e); } } - - /// - /// Interface for common debugger-decompiler mapping operations. - /// - [SDService] - public interface IDebuggerDecompilerService - { - /* - /// - /// Gets or sets the current method token and IL offset. Used for step in/out. - /// - Tuple DebugStepInformation { get; set; } - - /// - /// Checks the code mappings. - /// - bool CheckMappings(int typeToken); - - /// - /// Decompiles on demand a type. - /// - void DecompileOnDemand(TypeDefinition type); - - /// - /// Gets the IL from and IL to. - /// - bool GetILAndTokenByLineNumber(int typeToken, int lineNumber, out int[] ilRanges, out int memberToken); - - /// - /// Gets the ILRange and source code line number. - /// - bool GetILAndLineNumber(int typeToken, int memberToken, int ilOffset, out int[] ilRange, out int line, out bool isMatch); - - /// - /// Gets the local variables of a type and a member. - /// - IEnumerable GetLocalVariables(int typeToken, int memberToken); - - /// - /// Gets the local variable index. - /// - object GetLocalVariableIndex(int typeToken, int memberToken, string name); - - /// - /// Gets an implementation of an assembly resolver. - /// - /// Assembly file path. - /// An . - IAssemblyResolver GetAssemblyResolver(string assemblyFile); - */ - } } diff --git a/src/Main/Base/Project/Src/Services/Debugger/DecompiledBreakpointBookmark.cs b/src/Main/Base/Project/Src/Services/Debugger/DecompiledBreakpointBookmark.cs deleted file mode 100644 index 844a1ce21a..0000000000 --- a/src/Main/Base/Project/Src/Services/Debugger/DecompiledBreakpointBookmark.cs +++ /dev/null @@ -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; - } - - /// - /// Gets the assembly file and the type from the file name. - /// - /// true, if the operation succeded; false, otherwise. - 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; - } - } - */ -}