PageRenderTime 29ms CodeModel.GetById 17ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AssignmentExpression.cs

http://github.com/icsharpcode/ILSpy
C# | 304 lines | 228 code | 31 blank | 45 comment | 10 complexity | 3cb955bf039e7e1e33ac4b5fe3c87e71 MD5 | raw file
  1// 
  2// AssignmentExpression.cs
  3//
  4// Author:
  5//       Mike Kr├╝ger <mkrueger@novell.com>
  6// 
  7// Copyright (c) 2009 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.
 26
 27using System;
 28using System.Linq.Expressions;
 29using System.Collections.Generic;
 30
 31namespace ICSharpCode.NRefactory.CSharp
 32{
 33	/// <summary>
 34	/// Left Operator= Right
 35	/// </summary>
 36	public class AssignmentExpression : Expression
 37	{
 38		// reuse roles from BinaryOperatorExpression
 39		public readonly static Role<Expression> LeftRole = BinaryOperatorExpression.LeftRole;
 40		public readonly static Role<Expression> RightRole = BinaryOperatorExpression.RightRole;
 41		
 42		public readonly static TokenRole AssignRole = new TokenRole ("=");
 43		public readonly static TokenRole AddRole = new TokenRole ("+=");
 44		public readonly static TokenRole SubtractRole = new TokenRole ("-=");
 45		public readonly static TokenRole MultiplyRole = new TokenRole ("*=");
 46		public readonly static TokenRole DivideRole = new TokenRole ("/=");
 47		public readonly static TokenRole ModulusRole = new TokenRole ("%=");
 48		public readonly static TokenRole ShiftLeftRole = new TokenRole ("<<=");
 49		public readonly static TokenRole ShiftRightRole = new TokenRole (">>=");
 50		public readonly static TokenRole BitwiseAndRole = new TokenRole ("&=");
 51		public readonly static TokenRole BitwiseOrRole = new TokenRole ("|=");
 52		public readonly static TokenRole ExclusiveOrRole = new TokenRole ("^=");
 53		
 54		public AssignmentExpression()
 55		{
 56		}
 57		
 58		public AssignmentExpression(Expression left, Expression right)
 59		{
 60			this.Left = left;
 61			this.Right = right;
 62		}
 63		
 64		public AssignmentExpression(Expression left, AssignmentOperatorType op, Expression right)
 65		{
 66			this.Left = left;
 67			this.Operator = op;
 68			this.Right = right;
 69		}
 70		
 71		public AssignmentOperatorType Operator {
 72			get;
 73			set;
 74		}
 75		
 76		public Expression Left {
 77			get { return GetChildByRole (LeftRole); }
 78			set { SetChildByRole(LeftRole, value); }
 79		}
 80		
 81		public CSharpTokenNode OperatorToken {
 82			get { return GetChildByRole (GetOperatorRole(Operator)); }
 83		}
 84		
 85		public Expression Right {
 86			get { return GetChildByRole (RightRole); }
 87			set { SetChildByRole(RightRole, value); }
 88		}
 89		
 90		public override void AcceptVisitor (IAstVisitor visitor)
 91		{
 92			visitor.VisitAssignmentExpression (this);
 93		}
 94			
 95		public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
 96		{
 97			return visitor.VisitAssignmentExpression (this);
 98		}
 99		
100		public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
101		{
102			return visitor.VisitAssignmentExpression (this, data);
103		}
104		
105		protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
106		{
107			AssignmentExpression o = other as AssignmentExpression;
108			return o != null && (this.Operator == AssignmentOperatorType.Any || this.Operator == o.Operator)
109				&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);
110		}
111		
112		public static TokenRole GetOperatorRole(AssignmentOperatorType op)
113		{
114			switch (op) {
115				case AssignmentOperatorType.Assign:
116					return AssignRole;
117				case AssignmentOperatorType.Add:
118					return AddRole;
119				case AssignmentOperatorType.Subtract:
120					return SubtractRole;
121				case AssignmentOperatorType.Multiply:
122					return MultiplyRole;
123				case AssignmentOperatorType.Divide:
124					return DivideRole;
125				case AssignmentOperatorType.Modulus:
126					return ModulusRole;
127				case AssignmentOperatorType.ShiftLeft:
128					return ShiftLeftRole;
129				case AssignmentOperatorType.ShiftRight:
130					return ShiftRightRole;
131				case AssignmentOperatorType.BitwiseAnd:
132					return BitwiseAndRole;
133				case AssignmentOperatorType.BitwiseOr:
134					return BitwiseOrRole;
135				case AssignmentOperatorType.ExclusiveOr:
136					return ExclusiveOrRole;
137				default:
138					throw new NotSupportedException("Invalid value for AssignmentOperatorType");
139			}
140		}
141		
142		/// <summary>
143		/// Gets the binary operator for the specified compound assignment operator.
144		/// Returns null if 'op' is not a compound assignment.
145		/// </summary>
146		public static BinaryOperatorType? GetCorrespondingBinaryOperator(AssignmentOperatorType op)
147		{
148			switch (op) {
149				case AssignmentOperatorType.Assign:
150					return null;
151				case AssignmentOperatorType.Add:
152					return BinaryOperatorType.Add;
153				case AssignmentOperatorType.Subtract:
154					return BinaryOperatorType.Subtract;
155				case AssignmentOperatorType.Multiply:
156					return BinaryOperatorType.Multiply;
157				case AssignmentOperatorType.Divide:
158					return BinaryOperatorType.Divide;
159				case AssignmentOperatorType.Modulus:
160					return BinaryOperatorType.Modulus;
161				case AssignmentOperatorType.ShiftLeft:
162					return BinaryOperatorType.ShiftLeft;
163				case AssignmentOperatorType.ShiftRight:
164					return BinaryOperatorType.ShiftRight;
165				case AssignmentOperatorType.BitwiseAnd:
166					return BinaryOperatorType.BitwiseAnd;
167				case AssignmentOperatorType.BitwiseOr:
168					return BinaryOperatorType.BitwiseOr;
169				case AssignmentOperatorType.ExclusiveOr:
170					return BinaryOperatorType.ExclusiveOr;
171				default:
172					throw new NotSupportedException("Invalid value for AssignmentOperatorType");
173			}
174		}
175		
176		public static ExpressionType GetLinqNodeType(AssignmentOperatorType op, bool checkForOverflow)
177		{
178			switch (op) {
179				case AssignmentOperatorType.Assign:
180					return ExpressionType.Assign;
181				case AssignmentOperatorType.Add:
182					return checkForOverflow ? ExpressionType.AddAssignChecked : ExpressionType.AddAssign;
183				case AssignmentOperatorType.Subtract:
184					return checkForOverflow ? ExpressionType.SubtractAssignChecked : ExpressionType.SubtractAssign;
185				case AssignmentOperatorType.Multiply:
186					return checkForOverflow ? ExpressionType.MultiplyAssignChecked : ExpressionType.MultiplyAssign;
187				case AssignmentOperatorType.Divide:
188					return ExpressionType.DivideAssign;
189				case AssignmentOperatorType.Modulus:
190					return ExpressionType.ModuloAssign;
191				case AssignmentOperatorType.ShiftLeft:
192					return ExpressionType.LeftShiftAssign;
193				case AssignmentOperatorType.ShiftRight:
194					return ExpressionType.RightShiftAssign;
195				case AssignmentOperatorType.BitwiseAnd:
196					return ExpressionType.AndAssign;
197				case AssignmentOperatorType.BitwiseOr:
198					return ExpressionType.OrAssign;
199				case AssignmentOperatorType.ExclusiveOr:
200					return ExpressionType.ExclusiveOrAssign;
201				default:
202					throw new NotSupportedException("Invalid value for AssignmentOperatorType");
203			}
204		}
205
206		#region Builder methods
207		public override MemberReferenceExpression Member(string memberName)
208		{
209			return new MemberReferenceExpression { Target = this, MemberName = memberName };
210		}
211
212		public override IndexerExpression Indexer(IEnumerable<Expression> arguments)
213		{
214			IndexerExpression expr = new IndexerExpression();
215			expr.Target = new ParenthesizedExpression(this);
216			expr.Arguments.AddRange(arguments);
217			return expr;
218		}
219
220		public override IndexerExpression Indexer(params Expression[] arguments)
221		{
222			IndexerExpression expr = new IndexerExpression();
223			expr.Target = new ParenthesizedExpression(this);
224			expr.Arguments.AddRange(arguments);
225			return expr;
226		}
227
228		public override InvocationExpression Invoke(string methodName, IEnumerable<AstType> typeArguments, IEnumerable<Expression> arguments)
229		{
230			InvocationExpression ie = new InvocationExpression();
231			MemberReferenceExpression mre = new MemberReferenceExpression();
232			mre.Target = new ParenthesizedExpression(this);
233			mre.MemberName = methodName;
234			mre.TypeArguments.AddRange(typeArguments);
235			ie.Target = mre;
236			ie.Arguments.AddRange(arguments);
237			return ie;
238		}
239
240		public override InvocationExpression Invoke(IEnumerable<Expression> arguments)
241		{
242			InvocationExpression ie = new InvocationExpression();
243			ie.Target = new ParenthesizedExpression(this);
244			ie.Arguments.AddRange(arguments);
245			return ie;
246		}
247
248		public override InvocationExpression Invoke(params Expression[] arguments)
249		{
250			InvocationExpression ie = new InvocationExpression();
251			ie.Target = new ParenthesizedExpression(this);
252			ie.Arguments.AddRange(arguments);
253			return ie;
254		}
255
256		public override CastExpression CastTo(AstType type)
257		{
258			return new CastExpression { Type = type,  Expression = new ParenthesizedExpression(this) };
259		}
260
261		public override AsExpression CastAs(AstType type)
262		{
263			return new AsExpression { Type = type,  Expression = new ParenthesizedExpression(this) };
264		}
265
266		public override IsExpression IsType(AstType type)
267		{
268			return new IsExpression { Type = type,  Expression = new ParenthesizedExpression(this) };
269		}
270		#endregion
271	}
272	
273	public enum AssignmentOperatorType
274	{
275		/// <summary>left = right</summary>
276		Assign,
277		
278		/// <summary>left += right</summary>
279		Add,
280		/// <summary>left -= right</summary>
281		Subtract,
282		/// <summary>left *= right</summary>
283		Multiply,
284		/// <summary>left /= right</summary>
285		Divide,
286		/// <summary>left %= right</summary>
287		Modulus,
288		
289		/// <summary>left <<= right</summary>
290		ShiftLeft,
291		/// <summary>left >>= right</summary>
292		ShiftRight,
293		
294		/// <summary>left &= right</summary>
295		BitwiseAnd,
296		/// <summary>left |= right</summary>
297		BitwiseOr,
298		/// <summary>left ^= right</summary>
299		ExclusiveOr,
300		
301		/// <summary>Any operator (for pattern matching)</summary>
302		Any
303	}
304}