mirror of https://github.com/icsharpcode/ILSpy.git
5 changed files with 6 additions and 203 deletions
@ -1,195 +0,0 @@
@@ -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