Browse Source

Indexer decompilation support.

Conflicts:

	ICSharpCode.Decompiler/Ast/AstBuilder.cs
pull/70/head
Artur Zgodziski 15 years ago
parent
commit
ebd20b88c9
  1. 54
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 17
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs
  3. 8
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs
  4. 17
      NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

54
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -153,6 +153,7 @@ namespace ICSharpCode.Decompiler.Ast
TypeDefinition oldCurrentType = context.CurrentType; TypeDefinition oldCurrentType = context.CurrentType;
context.CurrentType = typeDef; context.CurrentType = typeDef;
TypeDeclaration astType = new TypeDeclaration(); TypeDeclaration astType = new TypeDeclaration();
ConvertAttributes(astType, typeDef);
astType.AddAnnotation(typeDef); astType.AddAnnotation(typeDef);
astType.Modifiers = ConvertModifiers(typeDef); astType.Modifiers = ConvertModifiers(typeDef);
astType.Name = CleanName(typeDef.Name); astType.Name = CleanName(typeDef.Name);
@ -216,7 +217,6 @@ namespace ICSharpCode.Decompiler.Ast
AddTypeMembers(astType, typeDef); AddTypeMembers(astType, typeDef);
} }
ConvertAttributes(astType, typeDef);
context.CurrentType = oldCurrentType; context.CurrentType = oldCurrentType;
return astType; return astType;
} }
@ -506,7 +506,25 @@ namespace ICSharpCode.Decompiler.Ast
// Add properties // Add properties
foreach(PropertyDefinition propDef in typeDef.Properties) { foreach(PropertyDefinition propDef in typeDef.Properties) {
astType.AddChild(CreateProperty(propDef), TypeDeclaration.MemberRole); MemberDeclaration astProp = CreateProperty(propDef);
if (astProp.Name == "Item" && propDef.HasParameters)
{
var defaultMember = GetDefaultMember(astType.Annotation<TypeDefinition>());
if (defaultMember.Item1 == "Item")
{
astProp = ConvertPropertyToIndexer((PropertyDeclaration)astProp, propDef);
var astAttr = astType.Attributes.SelectMany(sec => sec.Attributes).First(attr => attr.Annotation<CustomAttribute>() == defaultMember.Item2);
var attrSection = (AttributeSection)astAttr.Parent;
if (attrSection.Attributes.Count == 1)
attrSection.Remove();
else
astAttr.Remove();
}
}
astType.AddChild(astProp, TypeDeclaration.MemberRole);
} }
// Add constructors // Add constructors
@ -595,6 +613,19 @@ namespace ICSharpCode.Decompiler.Ast
return astMethod; return astMethod;
} }
IndexerDeclaration ConvertPropertyToIndexer(PropertyDeclaration astProp, PropertyDefinition propDef)
{
var astIndexer = new IndexerDeclaration();
astIndexer.Name = astProp.Name;
astIndexer.CopyAnnotationsFrom(astProp);
astIndexer.Modifiers = astProp.Modifiers;
astIndexer.ReturnType = astProp.ReturnType.Detach();
astIndexer.Getter = astProp.Getter.Detach();
astIndexer.Setter = astProp.Setter.Detach();
astIndexer.Parameters.AddRange(MakeParameters(propDef.Parameters));
return astIndexer;
}
PropertyDeclaration CreateProperty(PropertyDefinition propDef) PropertyDeclaration CreateProperty(PropertyDefinition propDef)
{ {
PropertyDeclaration astProp = new PropertyDeclaration(); PropertyDeclaration astProp = new PropertyDeclaration();
@ -894,6 +925,7 @@ namespace ICSharpCode.Decompiler.Ast
var attributes = new List<ICSharpCode.NRefactory.CSharp.Attribute>(); var attributes = new List<ICSharpCode.NRefactory.CSharp.Attribute>();
foreach (var customAttribute in customAttributeProvider.CustomAttributes) { foreach (var customAttribute in customAttributeProvider.CustomAttributes) {
var attribute = new ICSharpCode.NRefactory.CSharp.Attribute(); var attribute = new ICSharpCode.NRefactory.CSharp.Attribute();
attribute.AddAnnotation(customAttribute);
attribute.Type = ConvertType(customAttribute.AttributeType); attribute.Type = ConvertType(customAttribute.AttributeType);
attributes.Add(attribute); attributes.Add(attribute);
@ -1024,5 +1056,23 @@ namespace ICSharpCode.Decompiler.Ast
return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute"); return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute");
} }
/// <summary>
/// Gets the name of the default member of the type pointed by the <see cref="System.Reflection.DefaultMemberAttribute"/> attribute.
/// </summary>
/// <param name="type">The type definition.</param>
/// <returns>The name of the default member or null if no <see cref="System.Reflection.DefaultMemberAttribute"/> attribute has been found.</returns>
private static Tuple<string, CustomAttribute> GetDefaultMember(TypeDefinition type)
{
foreach (CustomAttribute ca in type.CustomAttributes)
{
if (ca.Constructor.FullName == "System.Void System.Reflection.DefaultMemberAttribute::.ctor(System.String)")
{
return Tuple.Create(ca.ConstructorArguments.Single().Value as string, ca);
}
}
return new Tuple<string,CustomAttribute>(null, null);
}
} }
} }

17
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs

@ -138,6 +138,21 @@ namespace AppliedToPropertySet
} }
} }
} }
//$$ AppliedToIndexer
namespace AppliedToIndexer
{
public class TestClass
{
[Obsolete("reason")]
public int this[int i]
{
get
{
return 0;
}
}
}
}
//$$ AppliedToDelegate //$$ AppliedToDelegate
[Obsolete("reason")] [Obsolete("reason")]
public delegate int AppliedToDelegate(); public delegate int AppliedToDelegate();
@ -361,7 +376,6 @@ namespace TargetPropertyIndexSetParam
[param: MyAttribute] [param: MyAttribute]
set set
{ {
return;
} }
} }
} }
@ -385,7 +399,6 @@ namespace TargetPropertyIndexSetMultiParam
[param: MyAttribute] [param: MyAttribute]
set set
{ {
return;
} }
} }
} }

8
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs

@ -56,8 +56,12 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.Body); } get { return GetChildByRole (Roles.Body); }
set { SetChildByRole (Roles.Body, value); } set { SetChildByRole (Roles.Body, value); }
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole(Roles.Parameter); }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitAccessor (this, data); return visitor.VisitAccessor (this, data);
} }

17
NRefactory/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -202,8 +202,21 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
WriteCommaSeparatedListInParenthesis(list.SafeCast<ParameterDeclaration, AstNode>(), spaceWithin); WriteCommaSeparatedListInParenthesis(list.SafeCast<ParameterDeclaration, AstNode>(), spaceWithin);
} }
#endif #endif
void WriteCommaSeparatedListInBrackets(IEnumerable<ParameterDeclaration> list, bool spaceWithin)
{
WriteToken("[", AstNode.Roles.LBracket);
if (list.Any())
{
Space(spaceWithin);
WriteCommaSeparatedList(list.SafeCast<ParameterDeclaration, AstNode>());
Space(spaceWithin);
}
WriteToken("]", AstNode.Roles.RBracket);
}
void WriteCommaSeparatedListInBrackets(IEnumerable<Expression> list) void WriteCommaSeparatedListInBrackets(IEnumerable<Expression> list)
{ {
WriteToken("[", AstNode.Roles.LBracket); WriteToken("[", AstNode.Roles.LBracket);
@ -1815,7 +1828,7 @@ namespace ICSharpCode.NRefactory.CSharp
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType); WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
WriteKeyword("this"); WriteKeyword("this");
Space(policy.BeforeMethodDeclarationParentheses); Space(policy.BeforeMethodDeclarationParentheses);
WriteCommaSeparatedListInParenthesis(indexerDeclaration.Parameters, policy.WithinMethodDeclarationParentheses); WriteCommaSeparatedListInBrackets(indexerDeclaration.Parameters, policy.WithinMethodDeclarationParentheses);
OpenBrace(policy.PropertyBraceStyle); OpenBrace(policy.PropertyBraceStyle);
// output get/set in their original order // output get/set in their original order
foreach (AstNode node in indexerDeclaration.Children) { foreach (AstNode node in indexerDeclaration.Children) {

Loading…
Cancel
Save