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

http://github.com/icsharpcode/ILSpy · C# · 230 lines · 152 code · 30 blank · 48 comment · 5 complexity · 0ca2d5b11068be7810b7fc37c92bf092 MD5 · raw file

  1. // Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.Collections.Generic;
  20. namespace ICSharpCode.NRefactory.CSharp
  21. {
  22. /// <summary>
  23. /// Base class for expressions.
  24. /// </summary>
  25. /// <remarks>
  26. /// This class is useful even though it doesn't provide any additional functionality:
  27. /// It can be used to communicate more information in APIs, e.g. "this subnode will always be an expression"
  28. /// </remarks>
  29. public abstract class Expression : AstNode
  30. {
  31. #region Null
  32. public new static readonly Expression Null = new NullExpression ();
  33. sealed class NullExpression : Expression
  34. {
  35. public override bool IsNull {
  36. get {
  37. return true;
  38. }
  39. }
  40. public override void AcceptVisitor (IAstVisitor visitor)
  41. {
  42. visitor.VisitNullNode(this);
  43. }
  44. public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
  45. {
  46. return visitor.VisitNullNode(this);
  47. }
  48. public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
  49. {
  50. return visitor.VisitNullNode(this, data);
  51. }
  52. protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
  53. {
  54. return other == null || other.IsNull;
  55. }
  56. }
  57. #endregion
  58. #region PatternPlaceholder
  59. public static implicit operator Expression(PatternMatching.Pattern pattern)
  60. {
  61. return pattern != null ? new PatternPlaceholder(pattern) : null;
  62. }
  63. sealed class PatternPlaceholder : Expression, PatternMatching.INode
  64. {
  65. readonly PatternMatching.Pattern child;
  66. public PatternPlaceholder(PatternMatching.Pattern child)
  67. {
  68. this.child = child;
  69. }
  70. public override NodeType NodeType {
  71. get { return NodeType.Pattern; }
  72. }
  73. public override void AcceptVisitor (IAstVisitor visitor)
  74. {
  75. visitor.VisitPatternPlaceholder(this, child);
  76. }
  77. public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
  78. {
  79. return visitor.VisitPatternPlaceholder(this, child);
  80. }
  81. public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
  82. {
  83. return visitor.VisitPatternPlaceholder(this, child, data);
  84. }
  85. protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
  86. {
  87. return child.DoMatch(other, match);
  88. }
  89. bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
  90. {
  91. return child.DoMatchCollection(role, pos, match, backtrackingInfo);
  92. }
  93. }
  94. #endregion
  95. public override NodeType NodeType {
  96. get {
  97. return NodeType.Expression;
  98. }
  99. }
  100. public new Expression Clone()
  101. {
  102. return (Expression)base.Clone();
  103. }
  104. public Expression ReplaceWith(Func<Expression, Expression> replaceFunction)
  105. {
  106. if (replaceFunction == null)
  107. throw new ArgumentNullException("replaceFunction");
  108. return (Expression)base.ReplaceWith(node => replaceFunction((Expression)node));
  109. }
  110. #region Builder methods
  111. /// <summary>
  112. /// Builds an member reference expression using this expression as target.
  113. /// </summary>
  114. public virtual MemberReferenceExpression Member(string memberName)
  115. {
  116. return new MemberReferenceExpression { Target = this, MemberName = memberName };
  117. }
  118. /// <summary>
  119. /// Builds an indexer expression using this expression as target.
  120. /// </summary>
  121. public virtual IndexerExpression Indexer(IEnumerable<Expression> arguments)
  122. {
  123. IndexerExpression expr = new IndexerExpression();
  124. expr.Target = this;
  125. expr.Arguments.AddRange(arguments);
  126. return expr;
  127. }
  128. /// <summary>
  129. /// Builds an indexer expression using this expression as target.
  130. /// </summary>
  131. public virtual IndexerExpression Indexer(params Expression[] arguments)
  132. {
  133. IndexerExpression expr = new IndexerExpression();
  134. expr.Target = this;
  135. expr.Arguments.AddRange(arguments);
  136. return expr;
  137. }
  138. /// <summary>
  139. /// Builds an invocation expression using this expression as target.
  140. /// </summary>
  141. public virtual InvocationExpression Invoke(string methodName, IEnumerable<Expression> arguments)
  142. {
  143. return Invoke(methodName, null, arguments);
  144. }
  145. /// <summary>
  146. /// Builds an invocation expression using this expression as target.
  147. /// </summary>
  148. public virtual InvocationExpression Invoke(string methodName, params Expression[] arguments)
  149. {
  150. return Invoke(methodName, null, arguments);
  151. }
  152. /// <summary>
  153. /// Builds an invocation expression using this expression as target.
  154. /// </summary>
  155. public virtual InvocationExpression Invoke(string methodName, IEnumerable<AstType> typeArguments, IEnumerable<Expression> arguments)
  156. {
  157. InvocationExpression ie = new InvocationExpression();
  158. MemberReferenceExpression mre = new MemberReferenceExpression();
  159. mre.Target = this;
  160. mre.MemberName = methodName;
  161. mre.TypeArguments.AddRange(typeArguments);
  162. ie.Target = mre;
  163. ie.Arguments.AddRange(arguments);
  164. return ie;
  165. }
  166. /// <summary>
  167. /// Builds an invocation expression using this expression as target.
  168. /// </summary>
  169. public virtual InvocationExpression Invoke(IEnumerable<Expression> arguments)
  170. {
  171. InvocationExpression ie = new InvocationExpression();
  172. ie.Target = this;
  173. ie.Arguments.AddRange(arguments);
  174. return ie;
  175. }
  176. /// <summary>
  177. /// Builds an invocation expression using this expression as target.
  178. /// </summary>
  179. public virtual InvocationExpression Invoke(params Expression[] arguments)
  180. {
  181. InvocationExpression ie = new InvocationExpression();
  182. ie.Target = this;
  183. ie.Arguments.AddRange(arguments);
  184. return ie;
  185. }
  186. public virtual CastExpression CastTo(AstType type)
  187. {
  188. return new CastExpression { Type = type, Expression = this };
  189. }
  190. public virtual AsExpression CastAs(AstType type)
  191. {
  192. return new AsExpression { Type = type, Expression = this };
  193. }
  194. public virtual IsExpression IsType(AstType type)
  195. {
  196. return new IsExpression { Type = type, Expression = this };
  197. }
  198. #endregion
  199. }
  200. }