Expression.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. //
  19. // Authors:
  20. // Antonello Provenzano <[email protected]>
  21. //
  22. using System.Collections.Generic;
  23. using System.Collections.ObjectModel;
  24. using System.Reflection;
  25. using System.Text;
  26. namespace System.Linq.Expressions
  27. {
  28. public abstract class Expression
  29. {
  30. #region .ctor
  31. protected Expression(ExpressionType nodeType, Type type)
  32. {
  33. this.nodeType = nodeType;
  34. this.type = type;
  35. }
  36. #endregion
  37. #region Fields
  38. private Type type;
  39. private ExpressionType nodeType;
  40. #endregion
  41. #region Properties
  42. public Type Type
  43. {
  44. get { return type; }
  45. }
  46. public ExpressionType NodeType
  47. {
  48. get { return nodeType; }
  49. }
  50. #endregion
  51. #region Private Static Methods
  52. private static void CheckLeftRight(Expression left, Expression right)
  53. {
  54. if (left == null)
  55. throw new ArgumentNullException("left");
  56. if (right == null)
  57. throw new ArgumentNullException("right");
  58. }
  59. #endregion
  60. #region Internal Methods
  61. internal virtual void BuildString(StringBuilder builder)
  62. {
  63. //TODO:
  64. }
  65. #endregion
  66. #region Public Methods
  67. public override string ToString()
  68. {
  69. //TODO: check this...
  70. StringBuilder builder = new StringBuilder();
  71. BuildString(builder);
  72. return builder.ToString();
  73. }
  74. #endregion
  75. #region Internal Static Methos
  76. internal static Type GetNonNullableType(Type type)
  77. {
  78. //TODO:
  79. return type;
  80. }
  81. internal static bool IsNullableType(Type type)
  82. {
  83. if (type == null)
  84. throw new ArgumentNullException("type");
  85. if (type.IsGenericType)
  86. {
  87. //TODO: check this...
  88. Type genType = type.GetGenericTypeDefinition();
  89. return typeof(Nullable<>).IsAssignableFrom(genType);
  90. }
  91. return false;
  92. }
  93. #endregion
  94. #region Public Static Methods
  95. public static BinaryExpression Add(Expression left, Expression right, MethodInfo method)
  96. {
  97. CheckLeftRight(left, right);
  98. // sine both the expressions define the same numeric type we don't have
  99. // to look for the "op_Addition" method...
  100. if (left.type == right.type &&
  101. ExpressionUtil.IsNumber (left.type))
  102. return new BinaryExpression(ExpressionType.Add, left, right, left.type);
  103. if (method == null)
  104. {
  105. method = ExpressionUtil.GetMethod("op_Addition", new Type[] { left.type, right.type });
  106. }
  107. if (method != null)
  108. {
  109. if (method.ReturnType == null) // it returns a void
  110. throw new ArgumentException();
  111. if (!method.IsStatic)
  112. throw new ArgumentException();
  113. ParameterInfo[] pars = method.GetParameters();
  114. if (pars.Length != 2)
  115. throw new ArgumentException();
  116. }
  117. return new BinaryExpression(ExpressionType.Add, left, right, method, method.ReturnType);
  118. }
  119. public static BinaryExpression Add(Expression left, Expression right)
  120. {
  121. return Add(left, right, null);
  122. }
  123. public static BinaryExpression AddChecked(Expression left, Expression right, MethodInfo method)
  124. {
  125. throw new NotImplementedException();
  126. }
  127. public static BinaryExpression AddChecked(Expression left, Expression right)
  128. {
  129. throw new NotImplementedException();
  130. }
  131. public static BinaryExpression And(Expression left, Expression right, MethodInfo method)
  132. {
  133. CheckLeftRight(left, right);
  134. throw new NotImplementedException();
  135. }
  136. public static BinaryExpression And(Expression left, Expression right)
  137. {
  138. return And(left, right, null);
  139. }
  140. public static BinaryExpression AndAlso(Expression left, Expression right, MethodInfo method)
  141. {
  142. throw new NotImplementedException();
  143. }
  144. public static BinaryExpression AndAlso(Expression left, Expression right)
  145. {
  146. return AndAlso(left, right, null);
  147. }
  148. public static MethodCallExpression ArrayIndex(Expression array, IEnumerable<Expression> indexes)
  149. {
  150. throw new NotImplementedException();
  151. }
  152. public static BinaryExpression ArrayIndex(Expression array, Expression index)
  153. {
  154. throw new NotImplementedException();
  155. }
  156. public static MethodCallExpression ArrayIndex(Expression array, params Expression[] indexes)
  157. {
  158. throw new NotImplementedException();
  159. }
  160. public static UnaryExpression ArrayLength(Expression array)
  161. {
  162. throw new NotImplementedException();
  163. }
  164. public static MemberAssignment Bind(MemberInfo member, Expression expression)
  165. {
  166. throw new NotImplementedException();
  167. }
  168. public static MemberAssignment Bind(MethodInfo propertyAccessor, Expression expression)
  169. {
  170. throw new NotImplementedException();
  171. }
  172. public static MethodCallExpression Call(Expression instance, MethodInfo method)
  173. {
  174. throw new NotImplementedException();
  175. }
  176. public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments)
  177. {
  178. throw new NotImplementedException();
  179. }
  180. public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments)
  181. {
  182. throw new NotImplementedException();
  183. }
  184. public static MethodCallExpression Call(Expression instance, MethodInfo method, IEnumerable<Expression> arguments)
  185. {
  186. throw new NotImplementedException();
  187. }
  188. public static MethodCallExpression Call(Expression instance, string methodName, Type[] typeArguments, params Expression[] arguments)
  189. {
  190. throw new NotImplementedException();
  191. }
  192. public static MethodCallExpression Call(Type type, string methodName, Type[] typeArguments, params Expression[] arguments)
  193. {
  194. throw new NotImplementedException();
  195. }
  196. public static MethodCallExpression CallVirtual(Expression instance, MethodInfo method)
  197. {
  198. throw new NotImplementedException();
  199. }
  200. public static MethodCallExpression CallVirtual(Expression instance, MethodInfo method, params Expression[] arguments)
  201. {
  202. throw new NotImplementedException();
  203. }
  204. public static MethodCallExpression CallVirtual(Expression instance, MethodInfo method, IEnumerable<Expression> arguments)
  205. {
  206. throw new NotImplementedException();
  207. }
  208. public static UnaryExpression Cast(Expression expression, Type type)
  209. {
  210. throw new NotImplementedException();
  211. }
  212. public static UnaryExpression Cast(Expression expression, Type type, MethodInfo method)
  213. {
  214. throw new NotImplementedException();
  215. }
  216. public static BinaryExpression Coalesce(Expression left, Expression right)
  217. {
  218. throw new NotImplementedException();
  219. }
  220. public static BinaryExpression Coalesce(Expression left, Expression right, MethodInfo conversion)
  221. {
  222. throw new NotImplementedException();
  223. }
  224. public static ConditionalExpression Condition(Expression test, Expression ifTrue, Expression ifFalse)
  225. {
  226. throw new NotImplementedException();
  227. }
  228. public static ConstantExpression Constant(object value)
  229. {
  230. Type valueType = null;
  231. if (value != null)
  232. valueType = value.GetType();
  233. return Constant(value, valueType);
  234. }
  235. public static ConstantExpression Constant(object value, Type type)
  236. {
  237. if (type == null)
  238. throw new ArgumentNullException("type");
  239. if (value == null && !IsNullableType(type))
  240. throw new ArgumentException();
  241. return new ConstantExpression(value, type);
  242. }
  243. public static UnaryExpression Convert(Expression expression, Type type)
  244. {
  245. throw new NotImplementedException();
  246. }
  247. public static UnaryExpression Convert(Expression expression, Type type, MethodInfo method)
  248. {
  249. throw new NotImplementedException();
  250. }
  251. public static UnaryExpression ConvertChecked(Expression expression, Type type)
  252. {
  253. throw new NotImplementedException();
  254. }
  255. public static UnaryExpression ConvertChecked(Expression expression, Type type, MethodInfo method)
  256. {
  257. throw new NotImplementedException();
  258. }
  259. public static BinaryExpression Divide(Expression left, Expression right)
  260. {
  261. return Divide(left, right);
  262. }
  263. public static BinaryExpression Divide(Expression left, Expression right, MethodInfo method)
  264. {
  265. CheckLeftRight(left, right);
  266. throw new NotImplementedException();
  267. }
  268. public static BinaryExpression Equal(Expression left, Expression right)
  269. {
  270. throw new NotImplementedException();
  271. }
  272. public static BinaryExpression Equal(Expression left, Expression right, bool liftToNull, MethodInfo method)
  273. {
  274. throw new NotImplementedException();
  275. }
  276. public static BinaryExpression ExclusiveOr(Expression left, Expression right)
  277. {
  278. throw new NotImplementedException();
  279. }
  280. public static BinaryExpression ExclusiveOr(Expression left, Expression right, MethodInfo method)
  281. {
  282. throw new NotImplementedException();
  283. }
  284. public static MemberExpression Field(Expression expression, FieldInfo field)
  285. {
  286. if (field == null)
  287. throw new ArgumentNullException("field");
  288. return new MemberExpression(expression, field, field.FieldType);
  289. }
  290. public static MemberExpression Field(Expression expression, string fieldName)
  291. {
  292. if (expression == null)
  293. throw new ArgumentNullException("expression");
  294. FieldInfo field = expression.Type.GetField(fieldName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  295. if (field == null)
  296. throw new ArgumentException();
  297. return Field(expression, field);
  298. }
  299. public static FuncletExpression Funclet(Funclet funclet, Type type)
  300. {
  301. if (funclet == null)
  302. throw new ArgumentNullException("funclet");
  303. if (type == null)
  304. throw new ArgumentNullException("type");
  305. return new FuncletExpression(funclet, type);
  306. }
  307. public static Type GetFuncType(params Type[] typeArgs)
  308. {
  309. if (typeArgs == null)
  310. throw new ArgumentNullException("typeArgs");
  311. if (typeArgs.Length > 5)
  312. throw new ArgumentException();
  313. return typeof(Func<,,,,>).MakeGenericType(typeArgs);
  314. }
  315. public static BinaryExpression GreaterThan(Expression left, Expression right)
  316. {
  317. throw new NotImplementedException();
  318. }
  319. public static BinaryExpression GreaterThan(Expression left, Expression right, bool liftToNull, MethodInfo method)
  320. {
  321. throw new NotImplementedException();
  322. }
  323. public static BinaryExpression GreaterThanOrEqual(Expression left, Expression right)
  324. {
  325. throw new NotImplementedException();
  326. }
  327. public static BinaryExpression GreaterThanOrEqual(Expression left, Expression right, bool liftToNull, MethodInfo method)
  328. {
  329. throw new NotImplementedException();
  330. }
  331. public static InvocationExpression Invoke(Expression expression, IEnumerable<Expression> arguments)
  332. {
  333. throw new NotImplementedException();
  334. }
  335. public static InvocationExpression Invoke(Expression expression, params Expression[] arguments)
  336. {
  337. throw new NotImplementedException();
  338. }
  339. public static Expression<TDelegate> Lambda<TDelegate>(Expression body, params ParameterExpression[] parameters)
  340. {
  341. throw new NotImplementedException();
  342. }
  343. public static Expression<TDelegate> Lambda<TDelegate>(Expression body, IEnumerable<ParameterExpression> parameters)
  344. {
  345. throw new NotImplementedException();
  346. }
  347. public static LambdaExpression Lambda(Expression body, params ParameterExpression[] parameters)
  348. {
  349. throw new NotImplementedException();
  350. }
  351. public static LambdaExpression Lambda(Type delegateType, Expression body, params ParameterExpression[] parameters)
  352. {
  353. throw new NotImplementedException();
  354. }
  355. public static LambdaExpression Lambda(Type delegateType, Expression body, IEnumerable<ParameterExpression> parameters)
  356. {
  357. throw new NotImplementedException();
  358. }
  359. public static BinaryExpression LeftShift(Expression left, Expression right)
  360. {
  361. throw new NotImplementedException();
  362. }
  363. public static BinaryExpression LeftShift(Expression left, Expression right, MethodInfo method)
  364. {
  365. throw new NotImplementedException();
  366. }
  367. public static BinaryExpression LessThan(Expression left, Expression right)
  368. {
  369. throw new NotImplementedException();
  370. }
  371. public static BinaryExpression LessThan(Expression left, Expression right, bool liftToNull, MethodInfo method)
  372. {
  373. throw new NotImplementedException();
  374. }
  375. public static BinaryExpression LessThanOrEqual(Expression left, Expression right)
  376. {
  377. throw new NotImplementedException();
  378. }
  379. public static BinaryExpression LessThanOrEqual(Expression left, Expression right, bool liftToNull, MethodInfo method)
  380. {
  381. throw new NotImplementedException();
  382. }
  383. /*
  384. public static LiftExpression Lift(Expression expression, IEnumerable<ParameterExpression> parameters, IEnumerable<Expression> arguments)
  385. {
  386. throw new NotImplementedException();
  387. }
  388. public static LiftExpression Lift(Expression expression, ParameterExpression parameter, Expression argument)
  389. {
  390. throw new NotImplementedException();
  391. }
  392. public static LiftExpression LiftEqual(Expression expression, IEnumerable<ParameterExpression> parameters, IEnumerable<Expression> arguments)
  393. {
  394. throw new NotImplementedException();
  395. }
  396. public static LiftExpression LiftFalse(Expression expression, IEnumerable<ParameterExpression> parameters, IEnumerable<Expression> arguments)
  397. {
  398. throw new NotImplementedException();
  399. }
  400. public static LiftExpression LiftFalse(Expression expression, ParameterExpression parameter, Expression argument)
  401. {
  402. throw new NotImplementedException();
  403. }
  404. public static LiftExpression LiftNotEqual(Expression expression, IEnumerable<ParameterExpression> parameters, IEnumerable<Expression> arguments)
  405. {
  406. throw new NotImplementedException();
  407. }
  408. public static LiftExpression LiftTrue(Expression expression, IEnumerable<ParameterExpression> parameters, IEnumerable<Expression> arguments)
  409. {
  410. throw new NotImplementedException();
  411. }
  412. public static LiftExpression LiftTrue(Expression expression, ParameterExpression parameter, Expression argument)
  413. {
  414. throw new NotImplementedException();
  415. }
  416. */
  417. public static MemberListBinding ListBind(MemberInfo member, params Expression[] initializers)
  418. {
  419. throw new NotImplementedException();
  420. }
  421. public static MemberListBinding ListBind(MemberInfo member, IEnumerable<Expression> initializers)
  422. {
  423. throw new NotImplementedException();
  424. }
  425. public static MemberListBinding ListBind(MethodInfo propertyAccessor, IEnumerable<Expression> initializers)
  426. {
  427. throw new NotImplementedException();
  428. }
  429. public static ListInitExpression ListInit(NewExpression newExpression, params Expression[] initializers)
  430. {
  431. if (initializers == null)
  432. throw new ArgumentNullException("inizializers");
  433. return ListInit(newExpression, ExpressionUtil.GetReadOnlyCollection (initializers));
  434. }
  435. public static ListInitExpression ListInit(NewExpression newExpression, IEnumerable<Expression> initializers)
  436. {
  437. if (newExpression == null)
  438. throw new ArgumentNullException("newExpression");
  439. if (initializers == null)
  440. throw new ArgumentNullException("inizializers");
  441. return new ListInitExpression(newExpression, ExpressionUtil.GetReadOnlyCollection(initializers));
  442. }
  443. public static MemberInitExpression MemberInit(NewExpression newExpression, IEnumerable<MemberBinding> bindings)
  444. {
  445. if (newExpression == null)
  446. throw new ArgumentNullException("newExpression");
  447. if (bindings == null)
  448. throw new ArgumentNullException("bindings");
  449. return new MemberInitExpression(newExpression, ExpressionUtil.GetReadOnlyCollection(bindings));
  450. }
  451. public static MemberExpression Property(Expression expression, PropertyInfo property)
  452. {
  453. if (property == null)
  454. throw new ArgumentNullException("property");
  455. MethodInfo getMethod = property.GetGetMethod(true);
  456. if (getMethod == null)
  457. throw new ArgumentException(); // to access the property we need to have
  458. // a get method...
  459. return new MemberExpression(expression, property, property.PropertyType);
  460. }
  461. public static MemberExpression Property(Expression expression, string propertyName)
  462. {
  463. if (expression == null)
  464. throw new ArgumentNullException("expression");
  465. PropertyInfo property = expression.Type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  466. if (property == null)
  467. throw new ArgumentException();
  468. return Property(expression, property);
  469. }
  470. public static MemberExpression PropertyOrField(Expression expression, string propertyOrFieldName)
  471. {
  472. if (expression == null)
  473. throw new ArgumentNullException("expression");
  474. PropertyInfo property = expression.Type.GetProperty(propertyOrFieldName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  475. if (property != null)
  476. return Property(expression, property);
  477. FieldInfo field = expression.Type.GetField(propertyOrFieldName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  478. if (field != null)
  479. return Field(expression, field);
  480. //TODO: should we return <null> here?
  481. // the name is not defined in the Type of the expression given...
  482. throw new ArgumentException();
  483. }
  484. public static UnaryExpression Quote(Expression expression)
  485. {
  486. if (expression == null)
  487. throw new ArgumentNullException("expression");
  488. //TODO: is this right?
  489. return new UnaryExpression(ExpressionType.Quote, expression, expression.GetType());
  490. }
  491. public static TypeBinaryExpression TypeIs(Expression expression, Type type)
  492. {
  493. if (expression == null)
  494. throw new ArgumentNullException("expression");
  495. if (type == null)
  496. throw new ArgumentNullException("type");
  497. return new TypeBinaryExpression(ExpressionType.TypeIs, expression, type, typeof(bool));
  498. }
  499. public static UnaryExpression TypeAs(Expression expression, Type type)
  500. {
  501. if (expression == null)
  502. throw new ArgumentNullException("expression");
  503. if (type == null)
  504. throw new ArgumentNullException("type");
  505. return new UnaryExpression(ExpressionType.TypeAs, expression, type);
  506. }
  507. #endregion
  508. }
  509. }