Browse Source

Add hyperlink support to decompiler.

pull/10/head
Daniel Grunwald 15 years ago
parent
commit
d997511d58
  1. 4
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 8
      ICSharpCode.Decompiler/Ast/AstMetodBodyBuilder.cs
  3. 17
      ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs
  4. 34
      ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs
  5. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  6. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs
  7. 3
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/IOutputFormatter.cs
  8. 2
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs
  9. 8
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/TextWriterOutputFormatter.cs

4
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -172,7 +172,7 @@ namespace Decompiler
} else if (type.IsNested) { } else if (type.IsNested) {
AstType typeRef = CreateType(type.DeclaringType, typeAttributes, ref typeIndex); AstType typeRef = CreateType(type.DeclaringType, typeAttributes, ref typeIndex);
string namepart = ICSharpCode.NRefactory.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name); string namepart = ICSharpCode.NRefactory.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name);
return new MemberType { Target = typeRef, MemberName = namepart }; return new MemberType { Target = typeRef, MemberName = namepart }.WithAnnotation(type);
} else { } else {
string ns = type.Namespace ?? string.Empty; string ns = type.Namespace ?? string.Empty;
string name = type.Name; string name = type.Name;
@ -190,7 +190,7 @@ namespace Decompiler
for (int i = 1; i < parts.Length; i++) { for (int i = 1; i < parts.Length; i++) {
nsType = new MemberType { Target = nsType, MemberName = parts[i] }; nsType = new MemberType { Target = nsType, MemberName = parts[i] };
} }
return new MemberType { Target = nsType, MemberName = name }; return new MemberType { Target = nsType, MemberName = name }.WithAnnotation(type);
} }
} }
} }

8
ICSharpCode.Decompiler/Ast/AstMetodBodyBuilder.cs

@ -542,7 +542,7 @@ namespace Decompiler
target = methodArgs[0]; target = methodArgs[0];
methodArgs.RemoveAt(0); methodArgs.RemoveAt(0);
} else { } else {
target = new Ast.IdentifierExpression(cecilMethod.DeclaringType.FullName); target = new TypeReferenceExpression { Type = AstBuilder.ConvertType(cecilMethod.DeclaringType)};
} }
// TODO: Constructors are ignored // TODO: Constructors are ignored
@ -552,10 +552,10 @@ namespace Decompiler
// TODO: Hack, detect properties properly // TODO: Hack, detect properties properly
if (cecilMethod.Name.StartsWith("get_")) { if (cecilMethod.Name.StartsWith("get_")) {
return target.Member(cecilMethod.Name.Remove(0, 4)); return target.Member(cecilMethod.Name.Remove(0, 4)).WithAnnotation(cecilMethod);
} else if (cecilMethod.Name.StartsWith("set_")) { } else if (cecilMethod.Name.StartsWith("set_")) {
return new Ast.AssignmentExpression( return new Ast.AssignmentExpression(
target.Member(cecilMethod.Name.Remove(0, 4)), target.Member(cecilMethod.Name.Remove(0, 4)).WithAnnotation(cecilMethod),
methodArgs[0] methodArgs[0]
); );
} }
@ -575,7 +575,7 @@ namespace Decompiler
}*/ }*/
// Default invocation // Default invocation
return target.Invoke(cecilMethod.Name, methodArgs); return target.Invoke(cecilMethod.Name, methodArgs).WithAnnotation(cecilMethod);
case Code.Calli: throw new NotImplementedException(); case Code.Calli: throw new NotImplementedException();
case Code.Castclass: return arg1.CastTo(operandAsTypeRef); case Code.Castclass: return arg1.CastTo(operandAsTypeRef);
case Code.Ckfinite: throw new NotImplementedException(); case Code.Ckfinite: throw new NotImplementedException();

17
ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs

@ -0,0 +1,17 @@
// 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 ICSharpCode.NRefactory.CSharp;
namespace Decompiler
{
static class NRefactoryExtensions
{
public static T WithAnnotation<T>(this T node, object annotation) where T : AstNode
{
node.AddAnnotation(annotation);
return node;
}
}
}

34
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -2,14 +2,18 @@
// This code is distributed under MIT X11 license (for details please see \doc\license.txt) // This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace Decompiler namespace Decompiler
{ {
public class TextOutputFormatter : IOutputFormatter public class TextOutputFormatter : IOutputFormatter
{ {
readonly ITextOutput output; readonly ITextOutput output;
readonly Stack<AstNode> nodeStack = new Stack<AstNode>();
public TextOutputFormatter(ITextOutput output) public TextOutputFormatter(ITextOutput output)
{ {
@ -20,7 +24,18 @@ namespace Decompiler
public void WriteIdentifier(string identifier) public void WriteIdentifier(string identifier)
{ {
output.Write(identifier); AstNode node = nodeStack.Peek();
MemberReference memberRef = node.Annotation<MemberReference>();
if (memberRef == null && node.Role == AstNode.Roles.TargetExpression
&& (node.Parent is InvocationExpression || node.Parent is ObjectCreateExpression))
{
memberRef = node.Parent.Annotation<MemberReference>();
}
if (memberRef != null)
output.WriteReference(identifier, memberRef);
else
output.Write(identifier);
} }
public void WriteKeyword(string keyword) public void WriteKeyword(string keyword)
@ -40,7 +55,8 @@ namespace Decompiler
public void OpenBrace(BraceStyle style) public void OpenBrace(BraceStyle style)
{ {
output.MarkFoldStart(); if (nodeStack.OfType<BlockStatement>().Count() <= 1)
output.MarkFoldStart();
output.WriteLine(" {"); output.WriteLine(" {");
output.Indent(); output.Indent();
} }
@ -49,7 +65,8 @@ namespace Decompiler
{ {
output.Unindent(); output.Unindent();
output.Write('}'); output.Write('}');
output.MarkFoldEnd(); if (nodeStack.OfType<BlockStatement>().Count() <= 1)
output.MarkFoldEnd();
} }
public void Indent() public void Indent()
@ -85,5 +102,16 @@ namespace Decompiler
break; break;
} }
} }
public void StartNode(AstNode node)
{
nodeStack.Push(node);
}
public void EndNode(AstNode node)
{
if (nodeStack.Pop() != node)
throw new InvalidOperationException();
}
} }
} }

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -52,6 +52,7 @@
<Compile Include="Ast\AstBuilder.cs" /> <Compile Include="Ast\AstBuilder.cs" />
<Compile Include="Ast\AstMetodBodyBuilder.cs" /> <Compile Include="Ast\AstMetodBodyBuilder.cs" />
<Compile Include="Ast\CommentStatement.cs" /> <Compile Include="Ast\CommentStatement.cs" />
<Compile Include="Ast\NRefactoryExtensions.cs" />
<Compile Include="Ast\TextOutputFormatter.cs" /> <Compile Include="Ast\TextOutputFormatter.cs" />
<Compile Include="Ast\Transforms\Idioms.cs" /> <Compile Include="Ast\Transforms\Idioms.cs" />
<Compile Include="Ast\Transforms\PushNegation.cs" /> <Compile Include="Ast\Transforms\PushNegation.cs" />

2
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs

@ -448,6 +448,8 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
if (annotation == null) if (annotation == null)
throw new ArgumentNullException("annotation"); throw new ArgumentNullException("annotation");
if (this.IsNull)
throw new InvalidOperationException("Cannot add annotations to the null node");
retry: // Retry until successful retry: // Retry until successful
object oldAnnotation = Interlocked.CompareExchange(ref this.annotations, annotation, null); object oldAnnotation = Interlocked.CompareExchange(ref this.annotations, annotation, null);
if (oldAnnotation == null) { if (oldAnnotation == null) {

3
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/IOutputFormatter.cs

@ -10,6 +10,9 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public interface IOutputFormatter public interface IOutputFormatter
{ {
void StartNode(AstNode node);
void EndNode(AstNode node);
/// <summary> /// <summary>
/// Writes an identifier. /// Writes an identifier.
/// If the identifier conflicts with a keyword, the output visitor will /// If the identifier conflicts with a keyword, the output visitor will

2
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -67,6 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteSpecialsUpToNode(node); WriteSpecialsUpToNode(node);
currentContainerNode = node; currentContainerNode = node;
positionStack.Push(node.FirstChild); positionStack.Push(node.FirstChild);
formatter.StartNode(node);
} }
object EndNode(AstNode node) object EndNode(AstNode node)
@ -76,6 +77,7 @@ namespace ICSharpCode.NRefactory.CSharp
Debug.Assert(pos == null || pos.Parent == node); Debug.Assert(pos == null || pos.Parent == node);
WriteSpecials(pos, null); WriteSpecials(pos, null);
currentContainerNode = node.Parent; currentContainerNode = node.Parent;
formatter.EndNode(node);
return null; return null;
} }
#endregion #endregion

8
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/TextWriterOutputFormatter.cs

@ -107,5 +107,13 @@ namespace ICSharpCode.NRefactory.CSharp
break; break;
} }
} }
public virtual void StartNode(AstNode node)
{
}
public virtual void EndNode(AstNode node)
{
}
} }
} }

Loading…
Cancel
Save