Browse Source

Add folding support.

pull/1/head
Daniel Grunwald 15 years ago
parent
commit
d07a18dc43
  1. 26
      ILSpy/Disassembler/ReflectionDisassembler.cs
  2. 4
      ILSpy/ITextOutput.cs
  3. 5
      ILSpy/TextView/DecompilerTextView.cs
  4. 3
      ILSpy/TextView/ILAsm-Mode.xshd
  5. 5
      ILSpy/TextView/SmartTextOutput.cs

26
ILSpy/Disassembler/ReflectionDisassembler.cs

@ -18,6 +18,7 @@ namespace ICSharpCode.ILSpy.Disassembler
ITextOutput output; ITextOutput output;
CancellationToken cancellationToken; CancellationToken cancellationToken;
bool detectControlStructure; bool detectControlStructure;
bool isInType; // whether we are currently disassembling a whole type (-> defaultCollapsed for foldings)
MethodBodyDisassembler methodBodyDisassembler; MethodBodyDisassembler methodBodyDisassembler;
public ReflectionDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken) public ReflectionDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken)
@ -123,9 +124,8 @@ namespace ICSharpCode.ILSpy.Disassembler
output.Write("unmanaged "); output.Write("unmanaged ");
WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl); WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl);
output.WriteLine();
output.Unindent(); output.Unindent();
OpenBlock(); OpenBlock(isInType);
WriteAttributes(method.CustomAttributes); WriteAttributes(method.CustomAttributes);
if (method.HasBody) if (method.HasBody)
@ -195,8 +195,8 @@ namespace ICSharpCode.ILSpy.Disassembler
WriteFlags(property.Attributes, propertyAttributes); WriteFlags(property.Attributes, propertyAttributes);
property.PropertyType.WriteTo(output); property.PropertyType.WriteTo(output);
output.Write(' '); output.Write(' ');
output.WriteLine(DisassemblerHelpers.Escape(property.Name)); output.Write(DisassemblerHelpers.Escape(property.Name));
OpenBlock(); OpenBlock(false);
WriteAttributes(property.CustomAttributes); WriteAttributes(property.CustomAttributes);
WriteNestedMethod(".get", property.GetMethod); WriteNestedMethod(".get", property.GetMethod);
WriteNestedMethod(".set", property.SetMethod); WriteNestedMethod(".set", property.SetMethod);
@ -235,8 +235,8 @@ namespace ICSharpCode.ILSpy.Disassembler
WriteFlags(ev.Attributes, eventAttributes); WriteFlags(ev.Attributes, eventAttributes);
ev.EventType.WriteTo(output); ev.EventType.WriteTo(output);
output.Write(' '); output.Write(' ');
output.WriteLine(DisassemblerHelpers.Escape(ev.Name)); output.Write(DisassemblerHelpers.Escape(ev.Name));
OpenBlock(); OpenBlock(false);
WriteAttributes(ev.CustomAttributes); WriteAttributes(ev.CustomAttributes);
WriteNestedMethod(".add", ev.AddMethod); WriteNestedMethod(".add", ev.AddMethod);
WriteNestedMethod(".remove", ev.RemoveMethod); WriteNestedMethod(".remove", ev.RemoveMethod);
@ -293,17 +293,19 @@ namespace ICSharpCode.ILSpy.Disassembler
const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask; const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;
WriteFlags(type.Attributes & ~masks, typeAttributes); WriteFlags(type.Attributes & ~masks, typeAttributes);
output.WriteLine(DisassemblerHelpers.Escape(type.Name)); output.Write(DisassemblerHelpers.Escape(type.Name));
if (type.BaseType != null) { if (type.BaseType != null) {
output.WriteLine();
output.Indent(); output.Indent();
output.Write("extends "); output.Write("extends ");
type.BaseType.WriteTo(output); type.BaseType.WriteTo(output);
output.Unindent(); output.Unindent();
output.WriteLine();
} }
OpenBlock(); OpenBlock(isInType);
bool oldIsInType = isInType;
isInType = true;
WriteAttributes(type.CustomAttributes); WriteAttributes(type.CustomAttributes);
if (type.HasLayoutInfo) { if (type.HasLayoutInfo) {
output.WriteLine(".pack {0}", type.PackingSize); output.WriteLine(".pack {0}", type.PackingSize);
@ -357,6 +359,7 @@ namespace ICSharpCode.ILSpy.Disassembler
output.WriteLine(); output.WriteLine();
} }
CloseBlock(); CloseBlock();
isInType = oldIsInType;
} }
#endregion #endregion
@ -394,9 +397,10 @@ namespace ICSharpCode.ILSpy.Disassembler
output.Write(")"); output.Write(")");
} }
void OpenBlock() void OpenBlock(bool defaultCollapsed)
{ {
output.MarkFoldStart(); output.MarkFoldStart(defaultCollapsed: defaultCollapsed);
output.WriteLine();
output.WriteLine("{"); output.WriteLine("{");
output.Indent(); output.Indent();
} }

4
ILSpy/ITextOutput.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.ILSpy
void WriteDefinition(string text, object definition); void WriteDefinition(string text, object definition);
void WriteReference(string text, object reference); void WriteReference(string text, object reference);
void MarkFoldStart(string collapsedText = "...", bool defaultClosed = false); void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false);
void MarkFoldEnd(); void MarkFoldEnd();
} }
@ -101,7 +101,7 @@ namespace ICSharpCode.ILSpy
Write(text); Write(text);
} }
void ITextOutput.MarkFoldStart(string collapsedText, bool defaultClosed) void ITextOutput.MarkFoldStart(string collapsedText, bool defaultCollapsed)
{ {
} }

5
ILSpy/TextView/DecompilerTextView.cs

@ -13,6 +13,7 @@ using System.Windows.Media.Animation;
using System.Windows.Threading; using System.Windows.Threading;
using System.Xml; using System.Xml;
using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Folding;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd; using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using Mono.Cecil; using Mono.Cecil;
@ -25,6 +26,7 @@ namespace ICSharpCode.ILSpy.TextView
sealed partial class DecompilerTextView : UserControl sealed partial class DecompilerTextView : UserControl
{ {
readonly ReferenceElementGenerator referenceElementGenerator; readonly ReferenceElementGenerator referenceElementGenerator;
readonly FoldingManager foldingManager;
internal MainWindow mainWindow; internal MainWindow mainWindow;
DefinitionLookup definitionLookup; DefinitionLookup definitionLookup;
@ -46,6 +48,7 @@ namespace ICSharpCode.ILSpy.TextView
this.referenceElementGenerator = new ReferenceElementGenerator(this); this.referenceElementGenerator = new ReferenceElementGenerator(this);
textEditor.TextArea.TextView.ElementGenerators.Add(referenceElementGenerator); textEditor.TextArea.TextView.ElementGenerators.Add(referenceElementGenerator);
textEditor.Text = "Welcome to ILSpy!"; textEditor.Text = "Welcome to ILSpy!";
foldingManager = FoldingManager.Install(textEditor.TextArea);
} }
public void Decompile(IEnumerable<ILSpyTreeNodeBase> treeNodes) public void Decompile(IEnumerable<ILSpyTreeNodeBase> treeNodes)
@ -66,12 +69,14 @@ namespace ICSharpCode.ILSpy.TextView
if (currentCancellationTokenSource == myCancellationTokenSource) { if (currentCancellationTokenSource == myCancellationTokenSource) {
currentCancellationTokenSource = null; currentCancellationTokenSource = null;
waitAdorner.Visibility = Visibility.Collapsed; waitAdorner.Visibility = Visibility.Collapsed;
foldingManager.Clear();
try { try {
SmartTextOutput textOutput = task.Result; SmartTextOutput textOutput = task.Result;
referenceElementGenerator.References = textOutput.References; referenceElementGenerator.References = textOutput.References;
definitionLookup = textOutput.DefinitionLookup; definitionLookup = textOutput.DefinitionLookup;
textEditor.SyntaxHighlighting = ILSpy.Language.Current.SyntaxHighlighting; textEditor.SyntaxHighlighting = ILSpy.Language.Current.SyntaxHighlighting;
textEditor.Text = textOutput.ToString(); textEditor.Text = textOutput.ToString();
foldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1);
} catch (AggregateException ex) { } catch (AggregateException ex) {
textEditor.SyntaxHighlighting = null; textEditor.SyntaxHighlighting = null;
referenceElementGenerator.References = null; referenceElementGenerator.References = null;

3
ILSpy/TextView/ILAsm-Mode.xshd

@ -1,9 +1,7 @@
<SyntaxDefinition name="ILAsm" extensions=".il" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008"> <SyntaxDefinition name="ILAsm" extensions=".il" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<Color name="Comment" foreground="Green" exampleText="// comment" /> <Color name="Comment" foreground="Green" exampleText="// comment" />
<Color name="String" foreground="Magenta" exampleText="&quot;Hello, World!&quot;" /> <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="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="Instructions" foreground="Blue" exampleText="nop;" />
<Color name="Keywords" foreground="Blue" fontWeight="bold" exampleText="true" /> <Color name="Keywords" foreground="Blue" fontWeight="bold" exampleText="true" />
<Color name="Directives" foreground="Green" fontWeight="bold" exampleText=".class" /> <Color name="Directives" foreground="Green" fontWeight="bold" exampleText=".class" />
@ -506,7 +504,6 @@
<Begin>"</Begin> <Begin>"</Begin>
<End>"</End> <End>"</End>
</Span> </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="NumberLiteral">\b0[xX][0-9a-fA-F]+|\b(\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule>
<!--<Rule color="Punctuation"> <!--<Rule color="Punctuation">
[?,.;()\[\]{}+\-/%*&lt;&gt;^+~!|&amp;]+ [?,.;()\[\]{}+\-/%*&lt;&gt;^+~!|&amp;]+

5
ILSpy/TextView/SmartTextOutput.cs

@ -129,9 +129,10 @@ namespace ICSharpCode.ILSpy.TextView
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference }); references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference });
} }
public void MarkFoldStart(string collapsedText, bool defaultClosed) public void MarkFoldStart(string collapsedText, bool defaultCollapsed)
{ {
openFoldings.Push(new NewFolding { StartOffset = b.Length, Name = collapsedText, DefaultClosed = defaultClosed }); WriteIndent();
openFoldings.Push(new NewFolding { StartOffset = b.Length, Name = collapsedText, DefaultClosed = defaultCollapsed });
} }
public void MarkFoldEnd() public void MarkFoldEnd()

Loading…
Cancel
Save