Browse Source

Add hidden sequence points for unmapped code.

pull/923/head
Daniel Grunwald 8 years ago
parent
commit
9d7fb0627d
  1. 27
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  2. 17
      ICSharpCode.Decompiler/IL/SequencePoint.cs
  3. 18
      ILSpy/Languages/CSharpILMixedLanguage.cs

27
ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.IL;
@ -131,8 +132,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -131,8 +132,12 @@ namespace ICSharpCode.Decompiler.CSharp
void EndSequencePoint(TextLocation startLocation, TextLocation endLocation)
{
if (current.Intervals.Count > 0 && current.Function != null) {
// use LongSet to deduplicate and merge the intervals
var longSet = new LongSet(current.Intervals.Select(i => new LongInterval(i.Start, i.End)));
Debug.Assert(!longSet.IsEmpty);
sequencePoints.Add((current.Function, new SequencePoint {
Offset = current.Intervals.Select(i => i.Start).Min(),
Offset = (int)longSet.Intervals[0].Start,
EndOffset = (int)longSet.Intervals[0].End,
StartLine = startLocation.Line,
StartColumn = startLocation.Column,
EndLine = endLocation.Line,
@ -183,8 +188,24 @@ namespace ICSharpCode.Decompiler.CSharp @@ -183,8 +188,24 @@ namespace ICSharpCode.Decompiler.CSharp
}
list.Add(sequencePoint);
}
foreach (var list in dict.Values) {
list.Sort((a, b) => a.Offset.CompareTo(b.Offset));
foreach (var (function, list) in dict.ToList()) {
// For each function, sort sequence points
// and insert hidden sequence points in the gaps.
var newList = new List<SequencePoint>();
int pos = 0;
foreach (var sequencePoint in list.OrderBy(sp => sp.Offset)) {
Debug.Assert(sequencePoint.Offset >= pos);
if (sequencePoint.Offset > pos) {
var hidden = new SequencePoint();
hidden.Offset = pos;
hidden.EndOffset = sequencePoint.Offset;
hidden.SetHidden();
newList.Add(hidden);
}
newList.Add(sequencePoint);
pos = sequencePoint.EndOffset;
}
dict[function] = newList;
}
return dict;
}

17
ICSharpCode.Decompiler/IL/SequencePoint.cs

@ -10,10 +10,20 @@ namespace ICSharpCode.Decompiler.IL @@ -10,10 +10,20 @@ namespace ICSharpCode.Decompiler.IL
public struct SequencePoint
{
/// <summary>
/// IL offset.
/// IL start offset.
/// </summary>
public int Offset { get; set; }
/// <summary>
/// IL end offset.
/// </summary>
/// <remarks>
/// This does not get stored in debug information;
/// it is used internally to create hidden sequence points
/// for the IL fragments not covered by any sequence point.
/// </remarks>
public int EndOffset { get; set; }
public int StartLine { get; set; }
public int StartColumn { get; set; }
public int EndLine { get; set; }
@ -22,5 +32,10 @@ namespace ICSharpCode.Decompiler.IL @@ -22,5 +32,10 @@ namespace ICSharpCode.Decompiler.IL
public bool IsHidden {
get { return StartLine == 0xfeefee && StartLine == EndLine; }
}
internal void SetHidden()
{
StartLine = EndLine = 0xfeefee;
}
}
}

18
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -82,9 +82,10 @@ namespace ICSharpCode.ILSpy @@ -82,9 +82,10 @@ namespace ICSharpCode.ILSpy
int index = sequencePoints.BinarySearch(instruction.Offset, seq => seq.Offset);
if (index >= 0) {
var info = sequencePoints[index];
var highlightingOutput = output as ISmartTextOutput;
if (!info.IsHidden) {
for (int line = info.StartLine; line <= info.EndLine; line++) {
if (output is ISmartTextOutput highlightingOutput) {
if (highlightingOutput != null) {
string text = codeLines[line - 1];
int startColumn = 1;
int endColumn = text.Length + 1;
@ -97,25 +98,28 @@ namespace ICSharpCode.ILSpy @@ -97,25 +98,28 @@ namespace ICSharpCode.ILSpy
WriteCommentLine(output, codeLines[line - 1]);
}
} else {
WriteCommentLine(output, "no code");
output.Write("// ");
highlightingOutput?.BeginSpan(gray);
output.WriteLine("(hidden sequence point)");
highlightingOutput?.EndSpan();
}
}
base.WriteInstruction(output, instruction);
}
HighlightingColor gray = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.DarkGray) };
HighlightingColor black = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.Black) };
void WriteHighlightedCommentLine(ISmartTextOutput output, string text, int startColumn, int endColumn, bool isSingleLine)
{
output.Write("// ");
output.BeginSpan(gray);
if (isSingleLine)
output.Write("// " + text.Substring(0, startColumn).TrimStart());
output.Write(text.Substring(0, startColumn).TrimStart());
else
output.Write("// " + text.Substring(0, startColumn));
output.BeginSpan(black);
output.Write(text.Substring(startColumn, endColumn - startColumn));
output.Write(text.Substring(0, startColumn));
output.EndSpan();
output.Write(text.Substring(startColumn, endColumn - startColumn));
output.BeginSpan(gray);
output.Write(text.Substring(endColumn));
output.EndSpan();
output.WriteLine();

Loading…
Cancel
Save