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