Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Ast/CSharpUtil.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 9 years ago

#2077: created branch and added first version

File size: 6.7 KB
Line 
1//
2// CSharpUtil.cs
3// 
4// Author:
5//       Mike KrÃŒger <mkrueger@novell.com>
6//
7// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26using System;
27using ICSharpCode.NRefactory.CSharp;
28using ICSharpCode.NRefactory.PatternMatching;
29
30namespace ICSharpCode.NRefactory.CSharp
31{
32  public static class CSharpUtil
33  {
34    /// <summary>
35    /// Inverts a boolean condition. Note: The condition object can be frozen (from AST) it's cloned internally.
36    /// </summary>
37    /// <param name="condition">The condition to invert.</param>
38    public static Expression InvertCondition(Expression condition)
39    {
40      return InvertConditionInternal(condition);
41    }
42   
43    static Expression InvertConditionInternal(Expression condition)
44    {
45      if (condition is ParenthesizedExpression) {
46        return new ParenthesizedExpression(InvertCondition(((ParenthesizedExpression)condition).Expression));
47      }
48     
49      if (condition is UnaryOperatorExpression) {
50        var uOp = (UnaryOperatorExpression)condition;
51        if (uOp.Operator == UnaryOperatorType.Not) {
52          if (!(uOp.Parent is Expression))
53            return GetInnerMostExpression(uOp.Expression).Clone();
54          return uOp.Expression.Clone();
55        }
56        return new UnaryOperatorExpression(UnaryOperatorType.Not, uOp.Clone());
57      }
58     
59      if (condition is BinaryOperatorExpression) {
60        var bOp = (BinaryOperatorExpression)condition;
61
62        if ((bOp.Operator == BinaryOperatorType.ConditionalAnd) || (bOp.Operator == BinaryOperatorType.ConditionalOr)) {
63          return new BinaryOperatorExpression(InvertCondition(bOp.Left), NegateConditionOperator(bOp.Operator), InvertCondition(bOp.Right));
64        } else if ((bOp.Operator == BinaryOperatorType.Equality) || (bOp.Operator == BinaryOperatorType.InEquality) || (bOp.Operator == BinaryOperatorType.GreaterThan)
65          || (bOp.Operator == BinaryOperatorType.GreaterThanOrEqual) || (bOp.Operator == BinaryOperatorType.LessThan) ||
66          (bOp.Operator == BinaryOperatorType.LessThanOrEqual)) {
67          return new BinaryOperatorExpression(bOp.Left.Clone(), NegateRelationalOperator(bOp.Operator), bOp.Right.Clone());
68        } else {
69          var negatedOp = NegateRelationalOperator(bOp.Operator);
70          if (negatedOp == BinaryOperatorType.Any)
71            return new UnaryOperatorExpression(UnaryOperatorType.Not, new ParenthesizedExpression(condition.Clone()));
72          bOp = (BinaryOperatorExpression)bOp.Clone();
73          bOp.Operator = negatedOp;
74          return bOp;
75        }
76      }
77      if (condition is ConditionalExpression) {
78        var cEx = condition.Clone() as ConditionalExpression;
79        cEx.Condition = InvertCondition(cEx.Condition);
80        return cEx;
81      }
82      if (condition is PrimitiveExpression) {
83        var pex = condition as PrimitiveExpression;
84        if (pex.Value is bool) {
85          return new PrimitiveExpression(!((bool)pex.Value));
86        }
87      }
88     
89      return new UnaryOperatorExpression(UnaryOperatorType.Not, AddParensForUnaryExpressionIfRequired(condition.Clone()));
90    }
91
92    /// <summary>
93    /// When negating an expression this is required, otherwise you would end up with
94    /// a or b -> !a or b
95    /// </summary>
96    internal static Expression AddParensForUnaryExpressionIfRequired(Expression expression)
97    {
98      if ((expression is BinaryOperatorExpression) ||
99          (expression is AssignmentExpression) ||
100          (expression is CastExpression) ||
101          (expression is AsExpression) ||
102          (expression is IsExpression) ||
103          (expression is LambdaExpression) ||
104          (expression is ConditionalExpression)) {
105        return new ParenthesizedExpression(expression);
106      }
107
108      return expression;
109    }
110
111    /// <summary>
112    /// Get negation of the specified relational operator
113    /// </summary>
114    /// <returns>
115    /// negation of the specified relational operator, or BinaryOperatorType.Any if it's not a relational operator
116    /// </returns>
117    public static BinaryOperatorType NegateRelationalOperator(BinaryOperatorType op)
118    {
119      switch (op) {
120        case BinaryOperatorType.GreaterThan:
121          return BinaryOperatorType.LessThanOrEqual;
122        case BinaryOperatorType.GreaterThanOrEqual:
123          return BinaryOperatorType.LessThan;
124        case BinaryOperatorType.Equality:
125          return BinaryOperatorType.InEquality;
126        case BinaryOperatorType.InEquality:
127          return BinaryOperatorType.Equality;
128        case BinaryOperatorType.LessThan:
129          return BinaryOperatorType.GreaterThanOrEqual;
130        case BinaryOperatorType.LessThanOrEqual:
131          return BinaryOperatorType.GreaterThan;
132        case BinaryOperatorType.ConditionalOr:
133          return BinaryOperatorType.ConditionalAnd;
134        case BinaryOperatorType.ConditionalAnd:
135          return BinaryOperatorType.ConditionalOr;
136      }
137      return BinaryOperatorType.Any;
138    }
139
140    /// <summary>
141    /// Returns true, if the specified operator is a relational operator
142    /// </summary>
143    public static bool IsRelationalOperator(BinaryOperatorType op)
144    {
145      return NegateRelationalOperator(op) != BinaryOperatorType.Any;
146    }
147
148    /// <summary>
149    /// Get negation of the condition operator
150    /// </summary>
151    /// <returns>
152    /// negation of the specified condition operator, or BinaryOperatorType.Any if it's not a condition operator
153    /// </returns>
154    public static BinaryOperatorType NegateConditionOperator(BinaryOperatorType op)
155    {
156      switch (op) {
157        case BinaryOperatorType.ConditionalOr:
158          return BinaryOperatorType.ConditionalAnd;
159        case BinaryOperatorType.ConditionalAnd:
160          return BinaryOperatorType.ConditionalOr;
161      }
162      return BinaryOperatorType.Any;
163    }
164
165    public static bool AreConditionsEqual(Expression cond1, Expression cond2)
166    {
167      if (cond1 == null || cond2 == null)
168        return false;
169      return GetInnerMostExpression(cond1).IsMatch(GetInnerMostExpression(cond2));
170    }
171
172    public static Expression GetInnerMostExpression(Expression target)
173    {
174      while (target is ParenthesizedExpression)
175        target = ((ParenthesizedExpression)target).Expression;
176      return target;
177    }
178  }
179}
180
Note: See TracBrowser for help on using the repository browser.