Browse Source

Don't use casts for implicit conversions to bool in conditional contexts.

pull/1423/head
Daniel Grunwald 6 years ago
parent
commit
976565264f
  1. 6
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 22
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

6
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -532,6 +532,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -532,6 +532,9 @@ namespace ICSharpCode.Decompiler.CSharp
internal ExpressionWithResolveResult LogicNot(TranslatedExpression expr)
{
// "!expr" implicitly converts to bool so we can remove the cast;
// but only if doing so wouldn't cause us to call a user-defined "operator !"
expr = expr.UnwrapImplicitBoolConversion(type => !type.GetMethods(m => m.IsOperator && m.Name == "op_LogicalNot").Any());
return new UnaryOperatorExpression(UnaryOperatorType.Not, expr.Expression)
.WithRR(new OperatorResolveResult(compilation.FindType(KnownTypeCode.Boolean), ExpressionType.Not, expr.ResolveResult));
}
@ -2476,6 +2479,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2476,6 +2479,7 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean)));
}
condition = condition.UnwrapImplicitBoolConversion();
trueBranch = AdjustConstantExpressionToType(trueBranch, falseBranch.Type);
falseBranch = AdjustConstantExpressionToType(falseBranch, trueBranch.Type);
@ -2522,7 +2526,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2522,7 +2526,7 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(rr);
}
}
protected internal override TranslatedExpression VisitAddressOf(AddressOf inst, TranslationContext context)
{
IType targetTypeHint = null;

22
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -431,7 +431,27 @@ namespace ICSharpCode.Decompiler.CSharp @@ -431,7 +431,27 @@ namespace ICSharpCode.Decompiler.CSharp
.WithoutILInstruction()
.WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), val));
}
/// <summary>
/// In conditional contexts, remove the bool-cast emitted when converting
/// an "implicit operator bool" invocation.
/// </summary>
public TranslatedExpression UnwrapImplicitBoolConversion(Func<IType, bool> typeFilter = null)
{
if (!this.Type.IsKnownType(KnownTypeCode.Boolean))
return this;
if (!(this.ResolveResult is ConversionResolveResult rr))
return this;
if (!(rr.Conversion.IsUserDefined && rr.Conversion.IsImplicit))
return this;
if (typeFilter != null && !typeFilter(rr.Input.Type))
return this;
if (this.Expression is CastExpression cast) {
return this.UnwrapChild(cast.Expression);
}
return this;
}
/// <summary>
/// Converts this expression to a boolean expression.
///

Loading…
Cancel
Save