Browse Source

Prefer types like 'char' and 'enum' in comparisons and for "??" and "?:".

pull/863/head
Daniel Grunwald 8 years ago
parent
commit
8da98180e7
  1. 41
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

41
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -480,12 +480,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -480,12 +480,9 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
// Special case comparisons with char literals
if (left.Type.IsKnownType(KnownTypeCode.Char) && MightBeCharLiteral(right.ResolveResult)) {
right = right.ConvertTo(left.Type, this);
} else if (right.Type.IsKnownType(KnownTypeCode.Char) && MightBeCharLiteral(left.ResolveResult)) {
left = left.ConvertTo(right.Type, this);
}
// Special case comparisons with enum and char literals
left = AdjustConstantExpressionToType(left, right.Type);
right = AdjustConstantExpressionToType(right, left.Type);
var rr = resolver.ResolveBinaryOperator(inst.Kind.ToBinaryOperatorType(), left.ResolveResult, right.ResolveResult)
as OperatorResolveResult;
@ -522,12 +519,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -522,12 +519,6 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(rr);
}
bool MightBeCharLiteral(ResolveResult rr)
{
return rr.IsCompileTimeConstant && rr.ConstantValue is int val
&& val >= char.MinValue && val <= char.MaxValue;
}
/// <summary>
/// Handle Comp instruction, operators other than equality/inequality.
/// </summary>
@ -1721,10 +1712,33 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1721,10 +1712,33 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(resolver.WithCheckForOverflow(inst.CheckForOverflow).ResolveUnaryOperator(op, target.ResolveResult));
}
/// <summary>
/// If expr is a constant integer expression, and its value fits into type,
/// convert the expression into the target type.
/// Otherwise, returns the expression unmodified.
/// </summary>
TranslatedExpression AdjustConstantExpressionToType(TranslatedExpression expr, IType type)
{
if (!expr.ResolveResult.IsCompileTimeConstant) {
return expr;
}
if (type.IsKnownType(KnownTypeCode.Boolean)
&& (object.Equals(expr.ResolveResult.ConstantValue, 0) || object.Equals(expr.ResolveResult.ConstantValue, 1))) {
return expr.ConvertToBoolean(this);
} else if (type.Kind == TypeKind.Enum || type.IsKnownType(KnownTypeCode.Char)) {
var castRR = resolver.WithCheckForOverflow(true).ResolveCast(type, expr.ResolveResult);
if (castRR.IsCompileTimeConstant && !castRR.IsError) {
return ConvertConstantValue(castRR).WithILInstruction(expr.ILInstructions);
}
}
return expr;
}
protected internal override TranslatedExpression VisitNullCoalescingInstruction(NullCoalescingInstruction inst, TranslationContext context)
{
var value = Translate(inst.ValueInst);
var fallback = Translate(inst.FallbackInst);
fallback = AdjustConstantExpressionToType(fallback, NullableType.GetUnderlyingType(value.Type));
var rr = resolver.ResolveBinaryOperator(BinaryOperatorType.NullCoalescing, value.ResolveResult, fallback.ResolveResult);
if (rr.IsError) {
IType targetType;
@ -1776,6 +1790,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1776,6 +1790,9 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean)));
}
trueBranch = AdjustConstantExpressionToType(trueBranch, falseBranch.Type);
falseBranch = AdjustConstantExpressionToType(falseBranch, trueBranch.Type);
var rr = resolver.ResolveConditional(condition.ResolveResult, trueBranch.ResolveResult, falseBranch.ResolveResult);
if (rr.IsError) {
IType targetType;

Loading…
Cancel
Save