Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ public abstract class Animal : LivingBeeing
{
[Computed]
public abstract bool IsPet { get; }

[Computed]
public abstract string SpeciesAndAge();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ public class Dog : Animal
{
public override string Species => "Canis lupus";
public override bool IsPet => true;

[Computed]
public override string SpeciesAndAge() => string.Concat(Species, " : ", Age);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ public class HoneyBee : Animal
public override string Species => "Apis mellifera";

public override bool IsPet => false;

[Computed]
public override string SpeciesAndAge() => string.Concat(Species, " : ", Age);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,28 @@ public void TestSelectMultipleLevelsOfAbstractMembersOverTphHierarchy()
}
}


[Test]
public void TestSelectAbstractMethodImplementedInDerivedCallingBasePropertyFromBaseType()
{
using (var env = new MethodEnvironment(classEnv))
{
//SETUP
var linq = env.Db.LivingBeeing.OfType<Animal>().ToList().Select(p => p.SpeciesAndAge()).ToList();

//ATTEMPT
env.AboutToUseDelegateDecompiler();
var dd = env.Db.LivingBeeing.OfType<Animal>().Select(p => p.SpeciesAndAge())
#if NO_AUTO_DECOMPILE
.Decompile()
#endif
.ToList();

//VERIFY
env.CompareAndLogList(linq, dd);
}
}

[Test]
public void TestSelectSelectMany()
{
Expand Down
25 changes: 22 additions & 3 deletions src/DelegateDecompiler/Processors/CallProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ static void Call(ProcessorState state, MethodInfo m)
static Expression BuildMethodCallExpression(MethodInfo m, Address instance, Expression[] arguments,
Address[] addresses)
{
var callInstance = AlignInstanceToDeclaringType(instance, m);

if (m.Name == "Add" && instance.Expression != null && typeof(IEnumerable).IsAssignableFrom(instance.Type))
{
switch (instance.Expression)
Expand All @@ -75,13 +77,13 @@ static Expression BuildMethodCallExpression(MethodInfo m, Address instance, Expr
{
if (m.Name.StartsWith("get_") && arguments.Length == 0)
{
return Expression.Property(instance, m);
return Expression.Property(callInstance, m);
}

if (m.Name.StartsWith("set_") && arguments.Length == 1)
{
var value = arguments.Single();
var property = Expression.Property(instance, m).Member;
var property = Expression.Property(callInstance, m).Member;
var expression = Processor.BuildAssignment(instance.Expression, property, value, out bool push);
if (push)
{
Expand Down Expand Up @@ -165,11 +167,28 @@ static Expression BuildMethodCallExpression(MethodInfo m, Address instance, Expr
}

if (instance.Expression != null)
return Expression.Call(instance, m, arguments);
return Expression.Call(callInstance, m, arguments);

return Expression.Call(null, m, arguments);
}

static Address AlignInstanceToDeclaringType(Address instance, MethodInfo method)
{
if (instance.Expression == null || method.DeclaringType == null)
{
return instance;
}

if (instance.Expression is UnaryExpression cast &&
cast.NodeType == ExpressionType.Convert &&
method.DeclaringType.IsAssignableFrom(cast.Operand.Type))
{
return cast.Operand;
}

return instance;
}

static bool TryParseOperator(MethodInfo m, out ExpressionType type)
{
switch (m.Name)
Expand Down