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. 28
      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 @@ -172,7 +172,7 @@ namespace Decompiler
} else if (type.IsNested) {
AstType typeRef = CreateType(type.DeclaringType, typeAttributes, ref typeIndex);
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 {
string ns = type.Namespace ?? string.Empty;
string name = type.Name;
@ -190,7 +190,7 @@ namespace Decompiler @@ -190,7 +190,7 @@ namespace Decompiler
for (int i = 1; i < parts.Length; 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 @@ -542,7 +542,7 @@ namespace Decompiler
target = methodArgs[0];
methodArgs.RemoveAt(0);
} else {
target = new Ast.IdentifierExpression(cecilMethod.DeclaringType.FullName);
target = new TypeReferenceExpression { Type = AstBuilder.ConvertType(cecilMethod.DeclaringType)};
}
// TODO: Constructors are ignored
@ -552,10 +552,10 @@ namespace Decompiler @@ -552,10 +552,10 @@ namespace Decompiler
// TODO: Hack, detect properties properly
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_")) {
return new Ast.AssignmentExpression(
target.Member(cecilMethod.Name.Remove(0, 4)),
target.Member(cecilMethod.Name.Remove(0, 4)).WithAnnotation(cecilMethod),
methodArgs[0]
);
}
@ -575,7 +575,7 @@ namespace Decompiler @@ -575,7 +575,7 @@ namespace Decompiler
}*/
// Default invocation
return target.Invoke(cecilMethod.Name, methodArgs);
return target.Invoke(cecilMethod.Name, methodArgs).WithAnnotation(cecilMethod);
case Code.Calli: throw new NotImplementedException();
case Code.Castclass: return arg1.CastTo(operandAsTypeRef);
case Code.Ckfinite: throw new NotImplementedException();

17
ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs

@ -0,0 +1,17 @@ @@ -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;
}
}
}

28
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -2,14 +2,18 @@ @@ -2,14 +2,18 @@
// 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 ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace Decompiler
{
public class TextOutputFormatter : IOutputFormatter
{
readonly ITextOutput output;
readonly Stack<AstNode> nodeStack = new Stack<AstNode>();
public TextOutputFormatter(ITextOutput output)
{
@ -20,6 +24,17 @@ namespace Decompiler @@ -20,6 +24,17 @@ namespace Decompiler
public void WriteIdentifier(string 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);
}
@ -40,6 +55,7 @@ namespace Decompiler @@ -40,6 +55,7 @@ namespace Decompiler
public void OpenBrace(BraceStyle style)
{
if (nodeStack.OfType<BlockStatement>().Count() <= 1)
output.MarkFoldStart();
output.WriteLine(" {");
output.Indent();
@ -49,6 +65,7 @@ namespace Decompiler @@ -49,6 +65,7 @@ namespace Decompiler
{
output.Unindent();
output.Write('}');
if (nodeStack.OfType<BlockStatement>().Count() <= 1)
output.MarkFoldEnd();
}
@ -85,5 +102,16 @@ namespace Decompiler @@ -85,5 +102,16 @@ namespace Decompiler
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 @@ @@ -52,6 +52,7 @@
<Compile Include="Ast\AstBuilder.cs" />
<Compile Include="Ast\AstMetodBodyBuilder.cs" />
<Compile Include="Ast\CommentStatement.cs" />
<Compile Include="Ast\NRefactoryExtensions.cs" />
<Compile Include="Ast\TextOutputFormatter.cs" />
<Compile Include="Ast\Transforms\Idioms.cs" />
<Compile Include="Ast\Transforms\PushNegation.cs" />

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

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

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

@ -10,6 +10,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -10,6 +10,9 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary>
public interface IOutputFormatter
{
void StartNode(AstNode node);
void EndNode(AstNode node);
/// <summary>
/// Writes an identifier.
/// 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 @@ -67,6 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteSpecialsUpToNode(node);
currentContainerNode = node;
positionStack.Push(node.FirstChild);
formatter.StartNode(node);
}
object EndNode(AstNode node)
@ -76,6 +77,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -76,6 +77,7 @@ namespace ICSharpCode.NRefactory.CSharp
Debug.Assert(pos == null || pos.Parent == node);
WriteSpecials(pos, null);
currentContainerNode = node.Parent;
formatter.EndNode(node);
return null;
}
#endregion

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

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

Loading…
Cancel
Save