mirror of https://github.com/icsharpcode/ILSpy.git
5 changed files with 6 additions and 203 deletions
@ -1,195 +0,0 @@ |
|||||||
//
|
|
||||||
// CSharpUtil.cs
|
|
||||||
//
|
|
||||||
// Author:
|
|
||||||
// Mike Krüger <mkrueger@novell.com>
|
|
||||||
//
|
|
||||||
// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.CSharp.Syntax |
|
||||||
{ |
|
||||||
public static class CSharpUtil |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Inverts a boolean condition. Note: The condition object can be frozen (from AST) it's cloned internally.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="condition">The condition to invert.</param>
|
|
||||||
public static Expression InvertCondition(Expression condition) |
|
||||||
{ |
|
||||||
return InvertConditionInternal(condition); |
|
||||||
} |
|
||||||
|
|
||||||
static Expression InvertConditionInternal(Expression condition) |
|
||||||
{ |
|
||||||
if (condition is ParenthesizedExpression) |
|
||||||
{ |
|
||||||
return new ParenthesizedExpression(InvertCondition(((ParenthesizedExpression)condition).Expression)); |
|
||||||
} |
|
||||||
|
|
||||||
if (condition is UnaryOperatorExpression) |
|
||||||
{ |
|
||||||
var uOp = (UnaryOperatorExpression)condition; |
|
||||||
if (uOp.Operator == UnaryOperatorType.Not) |
|
||||||
{ |
|
||||||
if (!(uOp.Parent is Expression)) |
|
||||||
return GetInnerMostExpression(uOp.Expression).Clone(); |
|
||||||
return uOp.Expression.Clone(); |
|
||||||
} |
|
||||||
return new UnaryOperatorExpression(UnaryOperatorType.Not, uOp.Clone()); |
|
||||||
} |
|
||||||
|
|
||||||
if (condition is BinaryOperatorExpression) |
|
||||||
{ |
|
||||||
var bOp = (BinaryOperatorExpression)condition; |
|
||||||
|
|
||||||
if ((bOp.Operator == BinaryOperatorType.ConditionalAnd) || (bOp.Operator == BinaryOperatorType.ConditionalOr)) |
|
||||||
{ |
|
||||||
return new BinaryOperatorExpression(InvertCondition(bOp.Left), NegateConditionOperator(bOp.Operator), InvertCondition(bOp.Right)); |
|
||||||
} |
|
||||||
else if ((bOp.Operator == BinaryOperatorType.Equality) || (bOp.Operator == BinaryOperatorType.InEquality) || (bOp.Operator == BinaryOperatorType.GreaterThan) |
|
||||||
|| (bOp.Operator == BinaryOperatorType.GreaterThanOrEqual) || (bOp.Operator == BinaryOperatorType.LessThan) || |
|
||||||
(bOp.Operator == BinaryOperatorType.LessThanOrEqual)) |
|
||||||
{ |
|
||||||
return new BinaryOperatorExpression(bOp.Left.Clone(), NegateRelationalOperator(bOp.Operator), bOp.Right.Clone()); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
var negatedOp = NegateRelationalOperator(bOp.Operator); |
|
||||||
if (negatedOp == BinaryOperatorType.Any) |
|
||||||
return new UnaryOperatorExpression(UnaryOperatorType.Not, new ParenthesizedExpression(condition.Clone())); |
|
||||||
bOp = (BinaryOperatorExpression)bOp.Clone(); |
|
||||||
bOp.Operator = negatedOp; |
|
||||||
return bOp; |
|
||||||
} |
|
||||||
} |
|
||||||
if (condition is ConditionalExpression) |
|
||||||
{ |
|
||||||
var cEx = condition.Clone() as ConditionalExpression; |
|
||||||
cEx.Condition = InvertCondition(cEx.Condition); |
|
||||||
return cEx; |
|
||||||
} |
|
||||||
if (condition is PrimitiveExpression) |
|
||||||
{ |
|
||||||
var pex = condition as PrimitiveExpression; |
|
||||||
if (pex.Value is bool) |
|
||||||
{ |
|
||||||
return new PrimitiveExpression(!((bool)pex.Value)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return new UnaryOperatorExpression(UnaryOperatorType.Not, AddParensForUnaryExpressionIfRequired(condition.Clone())); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// When negating an expression this is required, otherwise you would end up with
|
|
||||||
/// a or b -> !a or b
|
|
||||||
/// </summary>
|
|
||||||
internal static Expression AddParensForUnaryExpressionIfRequired(Expression expression) |
|
||||||
{ |
|
||||||
if ((expression is BinaryOperatorExpression) || |
|
||||||
(expression is AssignmentExpression) || |
|
||||||
(expression is CastExpression) || |
|
||||||
(expression is AsExpression) || |
|
||||||
(expression is IsExpression) || |
|
||||||
(expression is LambdaExpression) || |
|
||||||
(expression is ConditionalExpression)) |
|
||||||
{ |
|
||||||
return new ParenthesizedExpression(expression); |
|
||||||
} |
|
||||||
|
|
||||||
return expression; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get negation of the specified relational operator
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// negation of the specified relational operator, or BinaryOperatorType.Any if it's not a relational operator
|
|
||||||
/// </returns>
|
|
||||||
public static BinaryOperatorType NegateRelationalOperator(BinaryOperatorType op) |
|
||||||
{ |
|
||||||
switch (op) |
|
||||||
{ |
|
||||||
case BinaryOperatorType.GreaterThan: |
|
||||||
return BinaryOperatorType.LessThanOrEqual; |
|
||||||
case BinaryOperatorType.GreaterThanOrEqual: |
|
||||||
return BinaryOperatorType.LessThan; |
|
||||||
case BinaryOperatorType.Equality: |
|
||||||
return BinaryOperatorType.InEquality; |
|
||||||
case BinaryOperatorType.InEquality: |
|
||||||
return BinaryOperatorType.Equality; |
|
||||||
case BinaryOperatorType.LessThan: |
|
||||||
return BinaryOperatorType.GreaterThanOrEqual; |
|
||||||
case BinaryOperatorType.LessThanOrEqual: |
|
||||||
return BinaryOperatorType.GreaterThan; |
|
||||||
case BinaryOperatorType.ConditionalOr: |
|
||||||
return BinaryOperatorType.ConditionalAnd; |
|
||||||
case BinaryOperatorType.ConditionalAnd: |
|
||||||
return BinaryOperatorType.ConditionalOr; |
|
||||||
} |
|
||||||
return BinaryOperatorType.Any; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true, if the specified operator is a relational operator
|
|
||||||
/// </summary>
|
|
||||||
public static bool IsRelationalOperator(BinaryOperatorType op) |
|
||||||
{ |
|
||||||
return NegateRelationalOperator(op) != BinaryOperatorType.Any; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get negation of the condition operator
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// negation of the specified condition operator, or BinaryOperatorType.Any if it's not a condition operator
|
|
||||||
/// </returns>
|
|
||||||
public static BinaryOperatorType NegateConditionOperator(BinaryOperatorType op) |
|
||||||
{ |
|
||||||
switch (op) |
|
||||||
{ |
|
||||||
case BinaryOperatorType.ConditionalOr: |
|
||||||
return BinaryOperatorType.ConditionalAnd; |
|
||||||
case BinaryOperatorType.ConditionalAnd: |
|
||||||
return BinaryOperatorType.ConditionalOr; |
|
||||||
} |
|
||||||
return BinaryOperatorType.Any; |
|
||||||
} |
|
||||||
|
|
||||||
public static bool AreConditionsEqual(Expression cond1, Expression cond2) |
|
||||||
{ |
|
||||||
if (cond1 == null || cond2 == null) |
|
||||||
return false; |
|
||||||
return GetInnerMostExpression(cond1).IsMatch(GetInnerMostExpression(cond2)); |
|
||||||
} |
|
||||||
|
|
||||||
public static Expression GetInnerMostExpression(Expression target) |
|
||||||
{ |
|
||||||
while (target is ParenthesizedExpression) |
|
||||||
target = ((ParenthesizedExpression)target).Expression; |
|
||||||
return target; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Loading…
Reference in new issue