Browse Source

Add support for calling indexers. Closes #31.

pull/37/head
Daniel Grunwald 14 years ago
parent
commit
b9808b13bb
  1. 32
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 1
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  3. 50
      ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs

32
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -616,11 +616,22 @@ namespace Decompiler @@ -616,11 +616,22 @@ namespace Decompiler
if (prop.GetMethod == cecilMethodDef)
return target.Member(prop.Name).WithAnnotation(prop);
}
} else if (cecilMethodDef.IsGetter) { // with parameters
PropertyDefinition indexer = GetIndexer(cecilMethodDef);
if (indexer != null)
return target.Indexer(methodArgs).WithAnnotation(indexer);
} else if (cecilMethodDef.IsSetter && methodArgs.Count == 1) {
foreach (var prop in cecilMethodDef.DeclaringType.Properties) {
if (prop.SetMethod == cecilMethodDef)
return new Ast.AssignmentExpression(target.Member(prop.Name).WithAnnotation(prop), methodArgs[0]);
}
} else if (cecilMethodDef.IsSetter && methodArgs.Count > 1) {
PropertyDefinition indexer = GetIndexer(cecilMethodDef);
if (indexer != null)
return new AssignmentExpression(
target.Indexer(methodArgs.GetRange(0, methodArgs.Count - 1)).WithAnnotation(indexer),
methodArgs[methodArgs.Count - 1]
);
} else if (cecilMethodDef.IsAddOn && methodArgs.Count == 1) {
foreach (var ev in cecilMethodDef.DeclaringType.Events) {
if (ev.AddMethod == cecilMethodDef) {
@ -647,6 +658,27 @@ namespace Decompiler @@ -647,6 +658,27 @@ namespace Decompiler
return target.Invoke(cecilMethod.Name, ConvertTypeArguments(cecilMethod), methodArgs).WithAnnotation(cecilMethod);
}
static PropertyDefinition GetIndexer(MethodDefinition cecilMethodDef)
{
TypeDefinition typeDef = cecilMethodDef.DeclaringType;
string indexerName = null;
foreach (CustomAttribute ca in typeDef.CustomAttributes) {
if (ca.Constructor.FullName == "System.Void System.Reflection.DefaultMemberAttribute::.ctor(System.String)") {
indexerName = ca.ConstructorArguments.Single().Value as string;
break;
}
}
if (indexerName == null)
return null;
foreach (PropertyDefinition prop in typeDef.Properties) {
if (prop.Name == indexerName) {
if (prop.GetMethod == cecilMethodDef || prop.SetMethod == cecilMethodDef)
return prop;
}
}
return null;
}
#if DEBUG
static readonly ConcurrentDictionary<ILCode, int> unhandledOpcodes = new ConcurrentDictionary<ILCode, int>();
#endif

1
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@
<ItemGroup>
<Compile Include="DelegateConstruction.cs" />
<Compile Include="Loops.cs" />
<Compile Include="PropertiesAndEvents.cs" />
<Compile Include="TestRunner.cs" />
</ItemGroup>
<ItemGroup>

50
ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
// 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.Text;
public class PropertiesAndEvents
{
public int Getter(StringBuilder b)
{
return b.Length;
}
public void Setter(StringBuilder b)
{
b.Capacity = 100;
}
public char IndexerGetter(StringBuilder b)
{
return b[50];
}
public void IndexerSetter(StringBuilder b)
{
b[42] = 'b';
}
public int AutomaticProperty { get; set; }
public int CustomProperty {
get {
return this.AutomaticProperty;
}
set {
this.AutomaticProperty = value;
}
}
public event EventHandler AutomaticEvent;
public event EventHandler CustomEvent {
add {
this.AutomaticEvent += value;
}
remove {
this.AutomaticEvent -= value;
}
}
}
Loading…
Cancel
Save