Browse Source

Move decompiler threading logic to new class (DecompilerTextView).

pull/1/head
Daniel Grunwald 14 years ago
parent
commit
d2e7be6cd4
  1. 3
      .gitignore
  2. 10
      ILSpy/ILSpy.csproj
  3. 107
      ILSpy/ITextOutput.cs
  4. 91
      ILSpy/MainWindow.xaml.cs
  5. 21
      ILSpy/TextView/CaretHighlightAdorner.cs
  6. 117
      ILSpy/TextView/DecompilerTextView.cs
  7. 525
      ILSpy/TextView/ILAsm-Mode.xshd
  8. 33
      ILSpy/TextView/ReferenceElementGenerator.cs
  9. 129
      ILSpy/TextView/SmartTextOutput.cs

3
.gitignore vendored

@ -1,2 +1,5 @@ @@ -1,2 +1,5 @@
bin/
obj/
/ICSharpCode.Decompiler/Properties/AssemblyInfo.cs
/ILSpy/Properties/AssemblyInfo.cs

10
ILSpy/ILSpy.csproj

@ -85,7 +85,6 @@ @@ -85,7 +85,6 @@
<Compile Include="AssemblyReferenceTreeNode.cs" />
<Compile Include="AssemblyTreeNode.cs" />
<Compile Include="BaseTypesTreeNode.cs" />
<Compile Include="CaretHighlightAdorner.cs" />
<Compile Include="CueBannerService.cs" />
<Compile Include="Decompiler\CSharpLanguage.cs" />
<Compile Include="Disassembler\DisassemblerHelpers.cs" />
@ -117,11 +116,15 @@ @@ -117,11 +116,15 @@
</Compile>
<Compile Include="PropertyTreeNode.cs" />
<Compile Include="ReferenceFolderTreeNode.cs" />
<Compile Include="ReferenceElementGenerator.cs" />
<Compile Include="ResourceListTreeNode.cs" />
<Compile Include="SortableGridViewColumn.cs" />
<Compile Include="TextView\CaretHighlightAdorner.cs" />
<Compile Include="TextView\DecompilerTextView.cs" />
<Compile Include="TextView\ReferenceElementGenerator.cs" />
<Compile Include="TextView\SmartTextOutput.cs" />
<Compile Include="TreeTraversal.cs" />
<Compile Include="TypeTreeNode.cs" />
<None Include="TextView\ILAsm-Mode.xshd" />
</ItemGroup>
<ItemGroup>
<Page Include="AboutDialog.xaml" />
@ -191,5 +194,8 @@ @@ -191,5 +194,8 @@
<Name>ICSharpCode.TreeView</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="TextView" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

107
ILSpy/ITextOutput.cs

@ -17,9 +17,6 @@ @@ -17,9 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.ILSpy
{
@ -34,108 +31,4 @@ namespace ICSharpCode.ILSpy @@ -34,108 +31,4 @@ namespace ICSharpCode.ILSpy
void WriteDefinition(string text, object definition);
void WriteReference(string text, object reference);
}
sealed class ReferenceSegment : TextSegment
{
public object Reference;
}
sealed class DefinitionLookup
{
Dictionary<object, int> definitions = new Dictionary<object, int>();
public int GetDefinitionPosition(object definition)
{
int val;
if (definitions.TryGetValue(definition, out val))
return val;
else
return -1;
}
public void AddDefinition(object definition, int offset)
{
definitions[definition] = offset;
}
}
sealed class SmartTextOutput : ITextOutput
{
readonly StringBuilder b = new StringBuilder();
int indent;
bool needsIndent;
TextSegmentCollection<ReferenceSegment> references = new TextSegmentCollection<ReferenceSegment>();
public readonly DefinitionLookup DefinitionLookup = new DefinitionLookup();
public TextSegmentCollection<ReferenceSegment> References {
get { return references; }
}
public override string ToString()
{
return b.ToString();
}
public void Indent()
{
indent++;
}
public void Unindent()
{
indent--;
}
void WriteIndent()
{
if (needsIndent) {
needsIndent = false;
for (int i = 0; i < indent; i++) {
b.Append('\t');
}
}
}
public void Write(char ch)
{
WriteIndent();
b.Append(ch);
}
public void Write(string text)
{
WriteIndent();
b.Append(text);
}
public void WriteCommentLine(string comment)
{
WriteIndent();
b.AppendLine(comment);
needsIndent = true;
}
public void WriteLine()
{
b.AppendLine();
needsIndent = true;
}
public void WriteDefinition(string text, object definition)
{
WriteIndent();
b.Append(text);
this.DefinitionLookup.AddDefinition(definition, b.Length);
}
public void WriteReference(string text, object reference)
{
WriteIndent();
int start = b.Length;
b.Append(text);
int end = b.Length;
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference });
}
}
}

91
ILSpy/MainWindow.xaml.cs

@ -30,6 +30,7 @@ using System.Windows.Threading; @@ -30,6 +30,7 @@ using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.ILSpy.Disassembler;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.TreeView;
using Microsoft.Win32;
using Mono.Cecil;
@ -44,8 +45,8 @@ namespace ICSharpCode.ILSpy @@ -44,8 +45,8 @@ namespace ICSharpCode.ILSpy
public partial class MainWindow : Window
{
AssemblyList assemblyList = new AssemblyList();
DecompilerTextView decompilerTextView;
FilterSettings filterSettings = new FilterSettings();
ReferenceElementGenerator referenceElementGenerator;
static readonly System.Reflection.Assembly[] initialAssemblies = {
typeof(object).Assembly,
@ -64,9 +65,9 @@ namespace ICSharpCode.ILSpy @@ -64,9 +65,9 @@ namespace ICSharpCode.ILSpy
public MainWindow()
{
referenceElementGenerator = new ReferenceElementGenerator(this);
this.DataContext = filterSettings;
InitializeComponent();
decompilerTextView = new DecompilerTextView(this, textEditor);
languageComboBox.Items.Add(new Decompiler.CSharpLanguage());
languageComboBox.Items.Add(new Disassembler.ILLanguage(false));
@ -75,8 +76,6 @@ namespace ICSharpCode.ILSpy @@ -75,8 +76,6 @@ namespace ICSharpCode.ILSpy
textEditor.Text = "Welcome to ILSpy!";
textEditor.TextArea.TextView.ElementGenerators.Add(referenceElementGenerator);
AssemblyListTreeNode assemblyListTreeNode = new AssemblyListTreeNode(assemblyList);
assemblyListTreeNode.FilterSettings = filterSettings.Clone();
filterSettings.PropertyChanged += delegate {
@ -112,7 +111,11 @@ namespace ICSharpCode.ILSpy @@ -112,7 +111,11 @@ namespace ICSharpCode.ILSpy
#endif
}
void SelectNode(SharpTreeNode obj)
internal AssemblyList AssemblyList {
get { return assemblyList; }
}
internal void SelectNode(SharpTreeNode obj)
{
if (obj != null) {
foreach (SharpTreeNode node in obj.Ancestors())
@ -214,85 +217,9 @@ namespace ICSharpCode.ILSpy @@ -214,85 +217,9 @@ namespace ICSharpCode.ILSpy
}
}
DefinitionLookup definitionLookup;
CancellationTokenSource currentCancellationTokenSource;
void TreeView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (currentCancellationTokenSource != null)
currentCancellationTokenSource.Cancel();
var myCancellationTokenSource = new CancellationTokenSource();
currentCancellationTokenSource = myCancellationTokenSource;
var task = RunDecompiler(ILSpy.Language.Current,
treeView.SelectedItems.OfType<ILSpyTreeNode>().ToArray(),
myCancellationTokenSource.Token);
task.ContinueWith(
delegate {
try {
if (currentCancellationTokenSource == myCancellationTokenSource) {
currentCancellationTokenSource = null;
try {
SmartTextOutput textOutput = task.Result;
referenceElementGenerator.References = textOutput.References;
definitionLookup = textOutput.DefinitionLookup;
textEditor.SyntaxHighlighting = ILSpy.Language.Current.SyntaxHighlighting;
textEditor.Text = textOutput.ToString();
} catch (AggregateException ex) {
textEditor.SyntaxHighlighting = null;
referenceElementGenerator.References = null;
definitionLookup = null;
textEditor.Text = string.Join(Environment.NewLine, ex.InnerExceptions.Select(ie => ie.ToString()));
}
}
} finally {
myCancellationTokenSource.Dispose();
}
},
TaskScheduler.FromCurrentSynchronizationContext());
}
static Task<SmartTextOutput> RunDecompiler(ILSpy.Language language, ILSpyTreeNode[] nodes, CancellationToken cancellationToken)
{
return Task.Factory.StartNew(
delegate {
SmartTextOutput textOutput = new SmartTextOutput();
foreach (var node in nodes) {
cancellationToken.ThrowIfCancellationRequested();
node.Decompile(language, textOutput, cancellationToken);
}
return textOutput;
});
}
internal void JumpToReference(ReferenceSegment referenceSegment)
{
object reference = referenceSegment.Reference;
if (definitionLookup != null) {
int pos = definitionLookup.GetDefinitionPosition(reference);
if (pos >= 0) {
textEditor.TextArea.Focus();
textEditor.Select(pos, 0);
textEditor.ScrollTo(textEditor.TextArea.Caret.Line, textEditor.TextArea.Caret.Column);
Dispatcher.Invoke(DispatcherPriority.Background, new Action(
delegate {
CaretHighlightAdorner.DisplayCaretHighlightAnimation(textEditor.TextArea);
}));
return;
}
}
if (reference is TypeReference) {
SelectNode(assemblyList.FindTypeNode(((TypeReference)reference).Resolve()));
} else if (reference is MethodReference) {
SelectNode(assemblyList.FindMethodNode(((MethodReference)reference).Resolve()));
} else if (reference is FieldReference) {
SelectNode(assemblyList.FindFieldNode(((FieldReference)reference).Resolve()));
} else if (reference is PropertyReference) {
SelectNode(assemblyList.FindPropertyNode(((PropertyReference)reference).Resolve()));
} else if (reference is EventReference) {
SelectNode(assemblyList.FindEventNode(((EventReference)reference).Resolve()));
} else if (reference is AssemblyDefinition) {
SelectNode(assemblyList.Assemblies.FirstOrDefault(node => node.AssemblyDefinition == reference));
}
decompilerTextView.Decompile(treeView.SelectedItems.OfType<ILSpyTreeNodeBase>());
}
void LanguageComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)

21
ILSpy/CaretHighlightAdorner.cs → ILSpy/TextView/CaretHighlightAdorner.cs

@ -1,5 +1,20 @@ @@ -1,5 +1,20 @@
// 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)
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
@ -10,7 +25,7 @@ using System.Windows.Media.Animation; @@ -10,7 +25,7 @@ using System.Windows.Media.Animation;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.Editing;
namespace ICSharpCode.ILSpy
namespace ICSharpCode.ILSpy.TextView
{
/// <summary>
/// Animated rectangle around the caret.

117
ILSpy/TextView/DecompilerTextView.cs

@ -0,0 +1,117 @@ @@ -0,0 +1,117 @@
// 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.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TextView
{
/// <summary>
/// Manages the TextEditor showing the decompiled code.
/// </summary>
sealed class DecompilerTextView
{
readonly MainWindow mainWindow;
readonly TextEditor textEditor;
readonly ReferenceElementGenerator referenceElementGenerator;
DefinitionLookup definitionLookup;
CancellationTokenSource currentCancellationTokenSource;
public DecompilerTextView(MainWindow mainWindow, TextEditor textEditor)
{
if (mainWindow == null)
throw new ArgumentNullException("mainWindow");
if (textEditor == null)
throw new ArgumentNullException("textEditor");
this.mainWindow = mainWindow;
this.textEditor = textEditor;
this.referenceElementGenerator = new ReferenceElementGenerator(this);
textEditor.TextArea.TextView.ElementGenerators.Add(referenceElementGenerator);
}
public void Decompile(IEnumerable<ILSpyTreeNodeBase> treeNodes)
{
if (currentCancellationTokenSource != null)
currentCancellationTokenSource.Cancel();
var myCancellationTokenSource = new CancellationTokenSource();
currentCancellationTokenSource = myCancellationTokenSource;
var task = RunDecompiler(Language.Current, treeNodes.ToArray(), myCancellationTokenSource.Token);
task.ContinueWith(
delegate {
try {
if (currentCancellationTokenSource == myCancellationTokenSource) {
currentCancellationTokenSource = null;
try {
SmartTextOutput textOutput = task.Result;
referenceElementGenerator.References = textOutput.References;
definitionLookup = textOutput.DefinitionLookup;
textEditor.SyntaxHighlighting = ILSpy.Language.Current.SyntaxHighlighting;
textEditor.Text = textOutput.ToString();
} catch (AggregateException ex) {
textEditor.SyntaxHighlighting = null;
referenceElementGenerator.References = null;
definitionLookup = null;
textEditor.Text = string.Join(Environment.NewLine, ex.InnerExceptions.Select(ie => ie.ToString()));
}
}
} finally {
myCancellationTokenSource.Dispose();
}
},
TaskScheduler.FromCurrentSynchronizationContext());
}
static Task<SmartTextOutput> RunDecompiler(Language language, ILSpyTreeNodeBase[] nodes, CancellationToken cancellationToken)
{
return Task.Factory.StartNew(
delegate {
SmartTextOutput textOutput = new SmartTextOutput();
foreach (var node in nodes) {
cancellationToken.ThrowIfCancellationRequested();
node.Decompile(language, textOutput, cancellationToken);
}
return textOutput;
});
}
internal void JumpToReference(ReferenceSegment referenceSegment)
{
object reference = referenceSegment.Reference;
if (definitionLookup != null) {
int pos = definitionLookup.GetDefinitionPosition(reference);
if (pos >= 0) {
textEditor.TextArea.Focus();
textEditor.Select(pos, 0);
textEditor.ScrollTo(textEditor.TextArea.Caret.Line, textEditor.TextArea.Caret.Column);
mainWindow.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
delegate {
CaretHighlightAdorner.DisplayCaretHighlightAnimation(textEditor.TextArea);
}));
return;
}
}
var assemblyList = mainWindow.AssemblyList;
if (reference is TypeReference) {
mainWindow.SelectNode(assemblyList.FindTypeNode(((TypeReference)reference).Resolve()));
} else if (reference is MethodReference) {
mainWindow.SelectNode(assemblyList.FindMethodNode(((MethodReference)reference).Resolve()));
} else if (reference is FieldReference) {
mainWindow.SelectNode(assemblyList.FindFieldNode(((FieldReference)reference).Resolve()));
} else if (reference is PropertyReference) {
mainWindow.SelectNode(assemblyList.FindPropertyNode(((PropertyReference)reference).Resolve()));
} else if (reference is EventReference) {
mainWindow.SelectNode(assemblyList.FindEventNode(((EventReference)reference).Resolve()));
} else if (reference is AssemblyDefinition) {
mainWindow.SelectNode(assemblyList.Assemblies.FirstOrDefault(node => node.AssemblyDefinition == reference));
}
}
}
}

525
ILSpy/TextView/ILAsm-Mode.xshd

@ -0,0 +1,525 @@ @@ -0,0 +1,525 @@
<SyntaxDefinition name="ILAsm" extensions=".il" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<Color name="Comment" foreground="Green" exampleText="// comment" />
<Color name="String" foreground="Magenta" exampleText="&quot;Hello, World!&quot;" />
<Color name="Punctuation" foreground="DarkGreen" exampleText="a(b.c);" />
<Color name="NumberLiteral" foreground="DarkBlue" exampleText="3.1415" />
<Color name="MethodCall" foreground="MidnightBlue" fontWeight="bold" exampleText="o.ToString();" />
<Color name="Instructions" foreground="Blue" exampleText="nop;" />
<Color name="Keywords" foreground="Blue" fontWeight="bold" exampleText="true" />
<Color name="Directives" foreground="Green" fontWeight="bold" exampleText=".class" />
<Color name="Security" foreground="Red" exampleText="request" />
<RuleSet ignoreCase="false">
<Keywords color="Instructions">
<Word>nop</Word>
<Word>break</Word>
<Word>ldarg.0</Word>
<Word>ldarg.1</Word>
<Word>ldarg.2</Word>
<Word>ldarg.3</Word>
<Word>ldloc.0</Word>
<Word>ldloc.1</Word>
<Word>ldloc.2</Word>
<Word>ldloc.3</Word>
<Word>stloc.0</Word>
<Word>stloc.1</Word>
<Word>stloc.2</Word>
<Word>stloc.3</Word>
<Word>ldarg.s</Word>
<Word>ldarga.s</Word>
<Word>starg.s</Word>
<Word>ldloc.s</Word>
<Word>ldloca.s</Word>
<Word>stloc.s</Word>
<Word>ldnull</Word>
<Word>ldc.i4.m1</Word>
<Word>ldc.i4.0</Word>
<Word>ldc.i4.1</Word>
<Word>ldc.i4.2</Word>
<Word>ldc.i4.3</Word>
<Word>ldc.i4.4</Word>
<Word>ldc.i4.5</Word>
<Word>ldc.i4.6</Word>
<Word>ldc.i4.7</Word>
<Word>ldc.i4.8</Word>
<Word>ldc.i4.s</Word>
<Word>ldc.i4</Word>
<Word>ldc.i8</Word>
<Word>ldc.r4</Word>
<Word>ldc.r8</Word>
<Word>dup</Word>
<Word>pop</Word>
<Word>jmp</Word>
<Word>call</Word>
<Word>calli</Word>
<Word>ret</Word>
<Word>br.s</Word>
<Word>brfalse.s</Word>
<Word>brtrue.s</Word>
<Word>beq.s</Word>
<Word>bge.s</Word>
<Word>bgt.s</Word>
<Word>ble.s</Word>
<Word>blt.s</Word>
<Word>bne.un.s</Word>
<Word>bge.un.s</Word>
<Word>bgt.un.s</Word>
<Word>ble.un.s</Word>
<Word>blt.un.s</Word>
<Word>br</Word>
<Word>brfalse</Word>
<Word>brtrue</Word>
<Word>beq</Word>
<Word>bge</Word>
<Word>bgt</Word>
<Word>ble</Word>
<Word>blt</Word>
<Word>bne.un</Word>
<Word>bge.un</Word>
<Word>bgt.un</Word>
<Word>ble.un</Word>
<Word>blt.un</Word>
<Word>switch</Word>
<Word>ldind.i1</Word>
<Word>ldind.u1</Word>
<Word>ldind.i2</Word>
<Word>ldind.u2</Word>
<Word>ldind.i4</Word>
<Word>ldind.u4</Word>
<Word>ldind.i8</Word>
<Word>ldind.i</Word>
<Word>ldind.r4</Word>
<Word>ldind.r8</Word>
<Word>ldind.ref</Word>
<Word>stind.ref</Word>
<Word>stind.i1</Word>
<Word>stind.i2</Word>
<Word>stind.i4</Word>
<Word>stind.i8</Word>
<Word>stind.r4</Word>
<Word>stind.r8</Word>
<Word>add</Word>
<Word>sub</Word>
<Word>mul</Word>
<Word>div</Word>
<Word>div.un</Word>
<Word>rem</Word>
<Word>rem.un</Word>
<Word>and</Word>
<Word>or</Word>
<Word>xor</Word>
<Word>shl</Word>
<Word>shr</Word>
<Word>shr.un</Word>
<Word>neg</Word>
<Word>not</Word>
<Word>conv.i1</Word>
<Word>conv.i2</Word>
<Word>conv.i4</Word>
<Word>conv.i8</Word>
<Word>conv.r4</Word>
<Word>conv.r8</Word>
<Word>conv.u4</Word>
<Word>conv.u8</Word>
<Word>callvirt</Word>
<Word>cpobj</Word>
<Word>ldobj</Word>
<Word>ldstr</Word>
<Word>newobj</Word>
<Word>castclass</Word>
<Word>isinst</Word>
<Word>conv.r.un</Word>
<Word>unbox</Word>
<Word>throw</Word>
<Word>ldfld</Word>
<Word>ldflda</Word>
<Word>stfld</Word>
<Word>ldsfld</Word>
<Word>ldsflda</Word>
<Word>stsfld</Word>
<Word>stobj</Word>
<Word>conv.ovf.i1.un</Word>
<Word>conv.ovf.i2.un</Word>
<Word>conv.ovf.i4.un</Word>
<Word>conv.ovf.i8.un</Word>
<Word>conv.ovf.u1.un</Word>
<Word>conv.ovf.u2.un</Word>
<Word>conv.ovf.u4.un</Word>
<Word>conv.ovf.u8.un</Word>
<Word>conv.ovf.i.un</Word>
<Word>conv.ovf.u.un</Word>
<Word>box</Word>
<Word>newarr</Word>
<Word>ldlen</Word>
<Word>ldelema</Word>
<Word>ldelem.i1</Word>
<Word>ldelem.u1</Word>
<Word>ldelem.i2</Word>
<Word>ldelem.u2</Word>
<Word>ldelem.i4</Word>
<Word>ldelem.u4</Word>
<Word>ldelem.i8</Word>
<Word>ldelem.i</Word>
<Word>ldelem.r4</Word>
<Word>ldelem.r8</Word>
<Word>ldelem.ref</Word>
<Word>stelem.i</Word>
<Word>stelem.i1</Word>
<Word>stelem.i2</Word>
<Word>stelem.i4</Word>
<Word>stelem.i8</Word>
<Word>stelem.r4</Word>
<Word>stelem.r8</Word>
<Word>stelem.ref</Word>
<Word>conv.ovf.i1</Word>
<Word>conv.ovf.u1</Word>
<Word>conv.ovf.i2</Word>
<Word>conv.ovf.u2</Word>
<Word>conv.ovf.i4</Word>
<Word>conv.ovf.u4</Word>
<Word>conv.ovf.i8</Word>
<Word>conv.ovf.u8</Word>
<Word>refanyval</Word>
<Word>ckfinite</Word>
<Word>mkrefany</Word>
<Word>ldtoken</Word>
<Word>conv.u2</Word>
<Word>conv.u1</Word>
<Word>conv.i</Word>
<Word>conv.ovf.i</Word>
<Word>conv.ovf.u</Word>
<Word>add.ovf</Word>
<Word>add.ovf.un</Word>
<Word>mul.ovf</Word>
<Word>mul.ovf.un</Word>
<Word>sub.ovf</Word>
<Word>sub.ovf.un</Word>
<Word>endfinally</Word>
<Word>leave</Word>
<Word>leave.s</Word>
<Word>stind.i</Word>
<Word>conv.u</Word>
<Word>prefix7</Word>
<Word>prefix6</Word>
<Word>prefix5</Word>
<Word>prefix4</Word>
<Word>prefix3</Word>
<Word>prefix2</Word>
<Word>prefix1</Word>
<Word>prefixref</Word>
<Word>arglist</Word>
<Word>ceq</Word>
<Word>cgt</Word>
<Word>cgt.un</Word>
<Word>clt</Word>
<Word>clt.un</Word>
<Word>ldftn</Word>
<Word>ldvirtftn</Word>
<Word>ldarg</Word>
<Word>ldarga</Word>
<Word>starg</Word>
<Word>ldloc</Word>
<Word>ldloca</Word>
<Word>stloc</Word>
<Word>localloc</Word>
<Word>endfilter</Word>
<Word>unaligned.</Word>
<Word>volatile.</Word>
<Word>tail.</Word>
<Word>initobj</Word>
<Word>cpblk</Word>
<Word>initblk</Word>
<Word>rethrow</Word>
<Word>sizeof</Word>
<Word>refanytype</Word>
<Word>illegal</Word>
<Word>endmac</Word>
<Word>brnull</Word>
<Word>brnull.s</Word>
<Word>brzero</Word>
<Word>brzero.s</Word>
<Word>brinst</Word>
<Word>brinst.s</Word>
<Word>ldind.u8</Word>
<Word>ldelem.u8</Word>
<Word>ldc.i4.M1</Word>
<Word>endfault</Word>
</Keywords>
<Keywords color="Keywords">
<Word>void</Word>
<Word>bool</Word>
<Word>char</Word>
<Word>wchar</Word>
<Word>int</Word>
<Word>int8</Word>
<Word>int16</Word>
<Word>int32</Word>
<Word>int64</Word>
<Word>float</Word>
<Word>float32</Word>
<Word>float64</Word>
<Word>refany</Word>
<Word>typedref</Word>
<Word>object</Word>
<Word>string</Word>
<Word>native</Word>
<Word>unsigned</Word>
<Word>value</Word>
<Word>valuetype</Word>
<Word>class</Word>
<Word>const</Word>
<Word>vararg</Word>
<Word>default</Word>
<Word>stdcall</Word>
<Word>thiscall</Word>
<Word>fastcall</Word>
<Word>unmanaged</Word>
<Word>not_in_gc_heap</Word>
<Word>beforefieldinit</Word>
<Word>instance</Word>
<Word>filter</Word>
<Word>catch</Word>
<Word>static</Word>
<Word>public</Word>
<Word>private</Word>
<Word>synchronized</Word>
<Word>interface</Word>
<Word>extends</Word>
<Word>implements</Word>
<Word>handler</Word>
<Word>finally</Word>
<Word>fault</Word>
<Word>to</Word>
<Word>abstract</Word>
<Word>auto</Word>
<Word>sequential</Word>
<Word>explicit</Word>
<Word>wrapper</Word>
<Word>ansi</Word>
<Word>unicode</Word>
<Word>autochar</Word>
<Word>import</Word>
<Word>enum</Word>
<Word>virtual</Word>
<Word>notremotable</Word>
<Word>special</Word>
<Word>il</Word>
<Word>cil</Word>
<Word>optil</Word>
<Word>managed</Word>
<Word>preservesig</Word>
<Word>runtime</Word>
<Word>method</Word>
<Word>field</Word>
<Word>bytearray</Word>
<Word>final</Word>
<Word>sealed</Word>
<Word>specialname</Word>
<Word>family</Word>
<Word>assembly</Word>
<Word>famandassem</Word>
<Word>famorassem</Word>
<Word>privatescope</Word>
<Word>nested</Word>
<Word>hidebysig</Word>
<Word>newslot</Word>
<Word>rtspecialname</Word>
<Word>pinvokeimpl</Word>
<Word>unmanagedexp</Word>
<Word>reqsecobj</Word>
<Word>.ctor</Word>
<Word>.cctor</Word>
<Word>initonly</Word>
<Word>literal</Word>
<Word>notserialized</Word>
<Word>forwardref</Word>
<Word>internalcall</Word>
<Word>noinlining</Word>
<Word>nomangle</Word>
<Word>lasterr</Word>
<Word>winapi</Word>
<Word>cdecl</Word>
<Word>stdcall</Word>
<Word>thiscall</Word>
<Word>fastcall</Word>
<Word>as</Word>
<Word>pinned</Word>
<Word>modreq</Word>
<Word>modopt</Word>
<Word>serializable</Word>
<Word>at</Word>
<Word>tls</Word>
<Word>true</Word>
<Word>false</Word>
</Keywords>
<Keywords color="Directives">
<Word>.class</Word>
<Word>.namespace</Word>
<Word>.method</Word>
<Word>.field</Word>
<Word>.emitbyte</Word>
<Word>.try</Word>
<Word>.maxstack</Word>
<Word>.locals</Word>
<Word>.entrypoint</Word>
<Word>.zeroinit</Word>
<Word>.pdirect</Word>
<Word>.data</Word>
<Word>.event</Word>
<Word>.addon</Word>
<Word>.removeon</Word>
<Word>.fire</Word>
<Word>.other</Word>
<Word>protected</Word>
<Word>.property</Word>
<Word>.set</Word>
<Word>.get</Word>
<Word>default</Word>
<Word>.import</Word>
<Word>.permission</Word>
<Word>.permissionset</Word>
<Word>.line</Word>
<Word>.language</Word>
<Word>#line</Word>
</Keywords>
<Keywords color="Security">
<Word>request</Word>
<Word>demand</Word>
<Word>assert</Word>
<Word>deny</Word>
<Word>permitonly</Word>
<Word>linkcheck</Word>
<Word>inheritcheck</Word>
<Word>reqmin</Word>
<Word>reqopt</Word>
<Word>reqrefuse</Word>
<Word>prejitgrant</Word>
<Word>prejitdeny</Word>
<Word>noncasdemand</Word>
<Word>noncaslinkdemand</Word>
<Word>noncasinheritance</Word>
</Keywords>
<Keywords color="Directives">
<!-- custom value specifier -->
<Word>.custom</Word>
<!-- IL method attribute -->
<Word>init</Word>
<!-- Class layout directives -->
<Word>.size</Word>
<Word>.pack</Word>
<!-- Manifest-related keywords -->
<Word>.file</Word>
<Word>nometadata</Word>
<Word>.hash</Word>
<Word>.assembly</Word>
<Word>implicitcom</Word>
<Word>noappdomain</Word>
<Word>noprocess</Word>
<Word>nomachine</Word>
<Word>.publickey</Word>
<Word>.publickeytoken</Word>
<Word>algorithm</Word>
<Word>.ver</Word>
<Word>.locale</Word>
<Word>extern</Word>
<Word>.export</Word>
<Word>.manifestres</Word>
<Word>.mresource</Word>
<Word>.localized</Word>
<!-- Field marshaling keywords -->
<Word>.module</Word>
<Word>marshal</Word>
<Word>custom</Word>
<Word>sysstring</Word>
<Word>fixed</Word>
<Word>variant</Word>
<Word>currency</Word>
<Word>syschar</Word>
<Word>decimal</Word>
<Word>date</Word>
<Word>bstr</Word>
<Word>tbstr</Word>
<Word>lpstr</Word>
<Word>lpwstr</Word>
<Word>lptstr</Word>
<Word>objectref</Word>
<Word>iunknown</Word>
<Word>idispatch</Word>
<Word>struct</Word>
<Word>safearray</Word>
<Word>byvalstr</Word>
<Word>lpvoid</Word>
<Word>any</Word>
<Word>array</Word>
<Word>lpstruct</Word>
<!-- VTable fixup keywords -->
<Word>.vtfixup</Word>
<Word>fromunmanaged</Word>
<Word>callmostderived</Word>
<Word>.vtentry</Word>
<!-- Parameter attributes -->
<Word>in</Word>
<Word>out</Word>
<Word>opt</Word>
<Word>lcid</Word>
<Word>retval</Word>
<Word>.param</Word>
<!-- Method implementations -->
<Word>.override</Word>
<Word>with</Word>
<!-- VariantType keywords -->
<Word>null</Word>
<Word>error</Word>
<Word>hresult</Word>
<Word>carray</Word>
<Word>userdefined</Word>
<Word>record</Word>
<Word>filetime</Word>
<Word>blob</Word>
<Word>stream</Word>
<Word>storage</Word>
<Word>streamed_object</Word>
<Word>stored_object</Word>
<Word>blob_object</Word>
<Word>cf</Word>
<Word>clsid</Word>
<Word>vector</Word>
<!-- Null reference keyword for InitOpt -->
<Word>nullref</Word>
<!-- Header flags keywords -->
<Word>.subsystem</Word>
<Word>.corflags</Word>
<Word>alignment</Word>
<Word>.imagebase</Word>
</Keywords>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
<Span color="String">
<Begin>"</Begin>
<End>"</End>
</Span>
<Rule color="MethodCall">[\d\w_]+(?=(\s*\())</Rule>
<Rule color="NumberLiteral">\b0[xX][0-9a-fA-F]+|\b(\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule>
<!--<Rule color="Punctuation">
[?,.;()\[\]{}+\-/%*&lt;&gt;^+~!|&amp;]+
</Rule>-->
</RuleSet>
<RuleSet name="CommentMarkerSet" ignoreCase="false">
<Keywords foreground="#FFFF0000" fontWeight="bold">
<Word>TODO</Word>
<Word>FIXME</Word>
</Keywords>
<Keywords foreground="#EEE0E000" fontWeight="bold">
<Word>HACK</Word>
<Word>UNDONE</Word>
</Keywords>
</RuleSet>
</SyntaxDefinition>

33
ILSpy/ReferenceElementGenerator.cs → ILSpy/TextView/ReferenceElementGenerator.cs

@ -1,23 +1,38 @@ @@ -1,23 +1,38 @@
// 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)
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows.Input;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Rendering;
namespace ICSharpCode.ILSpy
namespace ICSharpCode.ILSpy.TextView
{
sealed class ReferenceElementGenerator : VisualLineElementGenerator
{
MainWindow parentWindow;
DecompilerTextView decompilerTextView;
public TextSegmentCollection<ReferenceSegment> References { get; set; }
public ReferenceElementGenerator(MainWindow parentWindow)
public ReferenceElementGenerator(DecompilerTextView decompilerTextView)
{
if (parentWindow == null)
throw new ArgumentNullException("parentWindow");
this.parentWindow = parentWindow;
if (decompilerTextView == null)
throw new ArgumentNullException("decompilerTextView");
this.decompilerTextView = decompilerTextView;
}
public override int GetFirstInterestedOffset(int startOffset)
@ -43,7 +58,7 @@ namespace ICSharpCode.ILSpy @@ -43,7 +58,7 @@ namespace ICSharpCode.ILSpy
internal void JumpToReference(ReferenceSegment referenceSegment)
{
parentWindow.JumpToReference(referenceSegment);
decompilerTextView.JumpToReference(referenceSegment);
}
}

129
ILSpy/TextView/SmartTextOutput.cs

@ -0,0 +1,129 @@ @@ -0,0 +1,129 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.ILSpy.TextView
{
sealed class ReferenceSegment : TextSegment
{
public object Reference;
}
sealed class DefinitionLookup
{
Dictionary<object, int> definitions = new Dictionary<object, int>();
public int GetDefinitionPosition(object definition)
{
int val;
if (definitions.TryGetValue(definition, out val))
return val;
else
return -1;
}
public void AddDefinition(object definition, int offset)
{
definitions[definition] = offset;
}
}
sealed class SmartTextOutput : ITextOutput
{
readonly StringBuilder b = new StringBuilder();
int indent;
bool needsIndent;
TextSegmentCollection<ReferenceSegment> references = new TextSegmentCollection<ReferenceSegment>();
public readonly DefinitionLookup DefinitionLookup = new DefinitionLookup();
public TextSegmentCollection<ReferenceSegment> References {
get { return references; }
}
public override string ToString()
{
return b.ToString();
}
public void Indent()
{
indent++;
}
public void Unindent()
{
indent--;
}
void WriteIndent()
{
if (needsIndent) {
needsIndent = false;
for (int i = 0; i < indent; i++) {
b.Append('\t');
}
}
}
public void Write(char ch)
{
WriteIndent();
b.Append(ch);
}
public void Write(string text)
{
WriteIndent();
b.Append(text);
}
public void WriteCommentLine(string comment)
{
WriteIndent();
b.AppendLine(comment);
needsIndent = true;
}
public void WriteLine()
{
b.AppendLine();
needsIndent = true;
}
public void WriteDefinition(string text, object definition)
{
WriteIndent();
b.Append(text);
this.DefinitionLookup.AddDefinition(definition, b.Length);
}
public void WriteReference(string text, object reference)
{
WriteIndent();
int start = b.Length;
b.Append(text);
int end = b.Length;
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference });
}
}
}
Loading…
Cancel
Save