PageRenderTime 79ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/Microsoft.Scripting/Hosting/ObjectOperations.cs

https://bitbucket.org/stefanrusek/xronos
C# | 1024 lines | 478 code | 136 blank | 410 comment | 11 complexity | 00b4f3e47dd29bea737d584f89e7b607 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if CODEPLEX_40
  16. using System;
  17. #else
  18. using System; using Microsoft;
  19. #endif
  20. using System.Collections.Generic;
  21. using System.Diagnostics;
  22. using System.Runtime.Remoting;
  23. using System.Security.Permissions;
  24. using Microsoft.Scripting.Runtime;
  25. using Microsoft.Scripting.Utils;
  26. #if CODEPLEX_40
  27. using System.Linq.Expressions;
  28. using System.Dynamic;
  29. #else
  30. using Microsoft.Linq.Expressions;
  31. using Microsoft.Scripting;
  32. #endif
  33. namespace Microsoft.Scripting.Hosting {
  34. /// <summary>
  35. /// ObjectOperations provide a large catalogue of object operations such as member access, conversions,
  36. /// indexing, and things like addition. There are several introspection and tool support services available
  37. /// for more advanced hosts.
  38. ///
  39. /// You get ObjectOperation instances from ScriptEngine, and they are bound to their engines for the semantics
  40. /// of the operations. There is a default instance of ObjectOperations you can share across all uses of the
  41. /// engine. However, very advanced hosts can create new instances.
  42. /// </summary>
  43. public sealed class ObjectOperations
  44. #if !SILVERLIGHT
  45. : MarshalByRefObject
  46. #endif
  47. {
  48. private readonly DynamicOperations _ops;
  49. private readonly ScriptEngine _engine;
  50. // friend class: DynamicOperations
  51. internal ObjectOperations(DynamicOperations ops, ScriptEngine engine) {
  52. Assert.NotNull(ops);
  53. Assert.NotNull(engine);
  54. _ops = ops;
  55. _engine = engine;
  56. }
  57. public ScriptEngine Engine {
  58. get { return _engine; }
  59. }
  60. #pragma warning disable 618
  61. #region Local Operations
  62. /// <summary>
  63. /// Returns true if the object can be called, false if it cannot.
  64. ///
  65. /// Even if an object is callable Call may still fail if an incorrect number of arguments or type of arguments are provided.
  66. /// </summary>
  67. public bool IsCallable(object obj) {
  68. return _ops.IsCallable(obj);
  69. }
  70. /// <summary>
  71. /// Invokes the provided object with the given parameters and returns the result.
  72. ///
  73. /// The prefered way of calling objects is to convert the object to a strongly typed delegate
  74. /// using the ConvertTo methods and then invoking that delegate.
  75. /// </summary>
  76. public object Invoke(object obj, params object[] parameters) {
  77. return _ops.Invoke(obj, parameters);
  78. }
  79. /// <summary>
  80. /// Invokes a member on the provided object with the given parameters and returns the result.
  81. /// </summary>
  82. public object InvokeMember(object obj, string memberName, params object[] parameters) {
  83. return _ops.InvokeMember(obj, memberName, parameters);
  84. }
  85. /// <summary>
  86. /// Creates a new instance from the provided object using the given parameters, and returns the result.
  87. /// </summary>
  88. public object CreateInstance(object obj, params object[] parameters) {
  89. return _ops.CreateInstance(obj, parameters);
  90. }
  91. /// <summary>
  92. /// Gets the member name from the object obj. Throws an exception if the member does not exist or is write-only.
  93. /// </summary>
  94. public object GetMember(object obj, string name) {
  95. return _ops.GetMember(obj, name);
  96. }
  97. /// <summary>
  98. /// Gets the member name from the object obj and converts it to the type T. Throws an exception if the
  99. /// member does not exist, is write-only, or cannot be converted.
  100. /// </summary>
  101. public T GetMember<T>(object obj, string name) {
  102. return _ops.GetMember<T>(obj, name);
  103. }
  104. /// <summary>
  105. /// Gets the member name from the object obj. Returns true if the member is successfully retrieved and
  106. /// stores the value in the value out param.
  107. /// </summary>
  108. public bool TryGetMember(object obj, string name, out object value) {
  109. return _ops.TryGetMember(obj, name, out value);
  110. }
  111. /// <summary>
  112. /// Returns true if the object has a member named name, false if the member does not exist.
  113. /// </summary>
  114. public bool ContainsMember(object obj, string name) {
  115. return _ops.ContainsMember(obj, name);
  116. }
  117. /// <summary>
  118. /// Removes the member name from the object obj. Returns true if the member was successfully removed
  119. /// or false if the member does not exist.
  120. /// </summary>
  121. public bool RemoveMember(object obj, string name) {
  122. return _ops.RemoveMember(obj, name);
  123. }
  124. /// <summary>
  125. /// Sets the member name on object obj to value.
  126. /// </summary>
  127. public void SetMember(object obj, string name, object value) {
  128. _ops.SetMember(obj, name, value);
  129. }
  130. /// <summary>
  131. /// Sets the member name on object obj to value. This overload can be used to avoid
  132. /// boxing and casting of strongly typed members.
  133. /// </summary>
  134. public void SetMember<T>(object obj, string name, T value) {
  135. _ops.SetMember<T>(obj, name, value);
  136. }
  137. /// <summary>
  138. /// Gets the member name from the object obj. Throws an exception if the member does not exist or is write-only.
  139. /// </summary>
  140. public object GetMember(object obj, string name, bool ignoreCase) {
  141. return _ops.GetMember(obj, name, ignoreCase);
  142. }
  143. /// <summary>
  144. /// Gets the member name from the object obj and converts it to the type T. Throws an exception if the
  145. /// member does not exist, is write-only, or cannot be converted.
  146. /// </summary>
  147. public T GetMember<T>(object obj, string name, bool ignoreCase) {
  148. return _ops.GetMember<T>(obj, name, ignoreCase);
  149. }
  150. /// <summary>
  151. /// Gets the member name from the object obj. Returns true if the member is successfully retrieved and
  152. /// stores the value in the value out param.
  153. /// </summary>
  154. public bool TryGetMember(object obj, string name, bool ignoreCase, out object value) {
  155. return _ops.TryGetMember(obj, name, ignoreCase, out value);
  156. }
  157. /// <summary>
  158. /// Returns true if the object has a member named name, false if the member does not exist.
  159. /// </summary>
  160. public bool ContainsMember(object obj, string name, bool ignoreCase) {
  161. return _ops.ContainsMember(obj, name, ignoreCase);
  162. }
  163. /// <summary>
  164. /// Removes the member name from the object obj. Returns true if the member was successfully removed
  165. /// or false if the member does not exist.
  166. /// </summary>
  167. public bool RemoveMember(object obj, string name, bool ignoreCase) {
  168. return _ops.RemoveMember(obj, name, ignoreCase);
  169. }
  170. /// <summary>
  171. /// Sets the member name on object obj to value.
  172. /// </summary>
  173. public void SetMember(object obj, string name, object value, bool ignoreCase) {
  174. _ops.SetMember(obj, name, value, ignoreCase);
  175. }
  176. /// <summary>
  177. /// Sets the member name on object obj to value. This overload can be used to avoid
  178. /// boxing and casting of strongly typed members.
  179. /// </summary>
  180. public void SetMember<T>(object obj, string name, T value, bool ignoreCase) {
  181. _ops.SetMember<T>(obj, name, value, ignoreCase);
  182. }
  183. /// <summary>
  184. /// Convers the object obj to the type T.
  185. /// </summary>
  186. public T ConvertTo<T>(object obj) {
  187. return _ops.ConvertTo<T>(obj);
  188. }
  189. /// <summary>
  190. /// Converts the object obj to the type type.
  191. /// </summary>
  192. public object ConvertTo(object obj, Type type) {
  193. ContractUtils.RequiresNotNull(type, "type");
  194. return _ops.ConvertTo(obj, type);
  195. }
  196. /// <summary>
  197. /// Converts the object obj to the type T. Returns true if the value can be converted, false if it cannot.
  198. /// </summary>
  199. public bool TryConvertTo<T>(object obj, out T result) {
  200. return _ops.TryConvertTo<T>(obj, out result);
  201. }
  202. /// <summary>
  203. /// Converts the object obj to the type type. Returns true if the value can be converted, false if it cannot.
  204. /// </summary>
  205. public bool TryConvertTo(object obj, Type type, out object result) {
  206. return _ops.TryConvertTo(obj, type, out result);
  207. }
  208. /// <summary>
  209. /// Converts the object obj to the type T including explicit conversions which may lose information.
  210. /// </summary>
  211. public T ExplicitConvertTo<T>(object obj) {
  212. return _ops.ExplicitConvertTo<T>(obj);
  213. }
  214. /// <summary>
  215. /// Converts the object obj to the type type including explicit conversions which may lose information.
  216. /// </summary>
  217. public object ExplicitConvertTo(object obj, Type type) {
  218. ContractUtils.RequiresNotNull(type, "type");
  219. return _ops.ExplicitConvertTo(obj, type);
  220. }
  221. /// <summary>
  222. /// Converts the object obj to the type T including explicit conversions which may lose information.
  223. ///
  224. /// Returns true if the value can be converted, false if it cannot.
  225. /// </summary>
  226. public bool TryExplicitConvertTo<T>(object obj, out T result) {
  227. return _ops.TryExplicitConvertTo<T>(obj, out result);
  228. }
  229. /// <summary>
  230. /// Converts the object obj to the type type including explicit conversions which may lose information.
  231. ///
  232. /// Returns true if the value can be converted, false if it cannot.
  233. /// </summary>
  234. public bool TryExplicitConvertTo(object obj, Type type, out object result) {
  235. return _ops.TryExplicitConvertTo(obj, type, out result);
  236. }
  237. /// <summary>
  238. /// Performs a generic unary operation on the specified target and returns the result.
  239. /// </summary>
  240. public object DoOperation(ExpressionType operation, object target) {
  241. return _ops.DoOperation<object, object>(operation, target);
  242. }
  243. /// <summary>
  244. /// Performs a generic unary operation on the strongly typed target and returns the value as the specified type
  245. /// </summary>
  246. public TResult DoOperation<TTarget, TResult>(ExpressionType operation, TTarget target) {
  247. return _ops.DoOperation<TTarget, TResult>(operation, target);
  248. }
  249. /// <summary>
  250. /// Performs the generic binary operation on the specified targets and returns the result.
  251. /// </summary>
  252. public object DoOperation(ExpressionType operation, object target, object other) {
  253. return _ops.DoOperation<object, object, object>(operation, target, other);
  254. }
  255. /// <summary>
  256. /// Peforms the generic binary operation on the specified strongly typed targets and returns
  257. /// the strongly typed result.
  258. /// </summary>
  259. public TResult DoOperation<TTarget, TOther, TResult>(ExpressionType operation, TTarget target, TOther other) {
  260. return _ops.DoOperation<TTarget, TOther, TResult>(operation, target, other);
  261. }
  262. /// <summary>
  263. /// Performs addition on the specified targets and returns the result. Throws an exception
  264. /// if the operation cannot be performed.
  265. /// </summary>
  266. public object Add(object self, object other) {
  267. return DoOperation(ExpressionType.Add, self, other);
  268. }
  269. /// <summary>
  270. /// Performs subtraction on the specified targets and returns the result. Throws an exception
  271. /// if the operation cannot be performed.
  272. /// </summary>
  273. public object Subtract(object self, object other) {
  274. return DoOperation(ExpressionType.Subtract, self, other);
  275. }
  276. /// <summary>
  277. /// Raises the first object to the power of the second object. Throws an exception
  278. /// if the operation cannot be performed.
  279. /// </summary>
  280. public object Power(object self, object other) {
  281. return DoOperation(ExpressionType.Power, self, other);
  282. }
  283. /// <summary>
  284. /// Multiplies the two objects. Throws an exception
  285. /// if the operation cannot be performed.
  286. /// </summary>
  287. public object Multiply(object self, object other) {
  288. return DoOperation(ExpressionType.Multiply, self, other);
  289. }
  290. /// <summary>
  291. /// Divides the first object by the second object. Throws an exception
  292. /// if the operation cannot be performed.
  293. /// </summary>
  294. public object Divide(object self, object other) {
  295. return DoOperation(ExpressionType.Divide, self, other);
  296. }
  297. /// <summary>
  298. /// Performs modulus of the 1st object by the second object. Throws an exception
  299. /// if the operation cannot be performed.
  300. /// </summary>
  301. public object Modulo(object self, object other) {
  302. return DoOperation(ExpressionType.Modulo, self, other);
  303. }
  304. /// <summary>
  305. /// Shifts the left object left by the right object. Throws an exception if the
  306. /// operation cannot be performed.
  307. /// </summary>
  308. public object LeftShift(object self, object other) {
  309. return DoOperation(ExpressionType.LeftShift, self, other);
  310. }
  311. /// <summary>
  312. /// Shifts the left object right by the right object. Throws an exception if the
  313. /// operation cannot be performed.
  314. /// </summary>
  315. public object RightShift(object self, object other) {
  316. return DoOperation(ExpressionType.RightShift, self, other);
  317. }
  318. /// <summary>
  319. /// Performs a bitwise-and of the two operands. Throws an exception if the operation
  320. /// cannot be performed.
  321. /// </summary>
  322. public object BitwiseAnd(object self, object other) {
  323. return DoOperation(ExpressionType.And, self, other);
  324. }
  325. /// <summary>
  326. /// Performs a bitwise-or of the two operands. Throws an exception if the operation
  327. /// cannot be performed.
  328. /// </summary>
  329. public object BitwiseOr(object self, object other) {
  330. return DoOperation(ExpressionType.Or, self, other);
  331. }
  332. /// <summary>
  333. /// Performs a exclusive-or of the two operands. Throws an exception if the operation
  334. /// cannot be performed.
  335. /// </summary>
  336. public object ExclusiveOr(object self, object other) {
  337. return DoOperation(ExpressionType.ExclusiveOr, self, other);
  338. }
  339. /// <summary>
  340. /// Compares the two objects and returns true if the left object is less than the right object.
  341. /// Throws an exception if hte comparison cannot be performed.
  342. /// </summary>
  343. public bool LessThan(object self, object other) {
  344. return _ops.DoOperation<object, object, bool>(ExpressionType.LessThan, self, other);
  345. }
  346. /// <summary>
  347. /// Compares the two objects and returns true if the left object is greater than the right object.
  348. /// Throws an exception if hte comparison cannot be performed.
  349. /// </summary>
  350. public bool GreaterThan(object self, object other) {
  351. return _ops.DoOperation<object, object, bool>(ExpressionType.GreaterThan, self, other);
  352. }
  353. /// <summary>
  354. /// Compares the two objects and returns true if the left object is less than or equal to the right object.
  355. /// Throws an exception if hte comparison cannot be performed.
  356. /// </summary>
  357. public bool LessThanOrEqual(object self, object other) {
  358. return _ops.DoOperation<object, object, bool>(ExpressionType.LessThanOrEqual, self, other);
  359. }
  360. /// <summary>
  361. /// Compares the two objects and returns true if the left object is greater than or equal to the right object.
  362. /// Throws an exception if hte comparison cannot be performed.
  363. /// </summary>
  364. public bool GreaterThanOrEqual(object self, object other) {
  365. return _ops.DoOperation<object, object, bool>(ExpressionType.GreaterThanOrEqual, self, other);
  366. }
  367. /// <summary>
  368. /// Compares the two objects and returns true if the left object is equal to the right object.
  369. /// Throws an exception if the comparison cannot be performed.
  370. /// </summary>
  371. public bool Equal(object self, object other) {
  372. return _ops.DoOperation<object, object, bool>(ExpressionType.Equal, self, other);
  373. }
  374. /// <summary>
  375. /// Compares the two objects and returns true if the left object is not equal to the right object.
  376. /// Throws an exception if hte comparison cannot be performed.
  377. /// </summary>
  378. public bool NotEqual(object self, object other) {
  379. return _ops.DoOperation<object, object, bool>(ExpressionType.NotEqual, self, other);
  380. }
  381. /// <summary>
  382. /// Returns a string which describes the object as it appears in source code
  383. /// </summary>
  384. [Obsolete("Use Format method instead.")]
  385. public string GetCodeRepresentation(object obj) {
  386. return obj.ToString();
  387. //return _ops.DoOperation<object, string>(StandardOperators.CodeRepresentation, obj);
  388. }
  389. /// <summary>
  390. /// Returns a string representation of the object in a language specific object display format.
  391. /// </summary>
  392. public string Format(object obj) {
  393. return _ops.Format(obj);
  394. }
  395. /// <summary>
  396. /// Returns a list of strings which contain the known members of the object.
  397. /// </summary>
  398. public IList<string> GetMemberNames(object obj) {
  399. return _ops.GetMemberNames(obj);
  400. }
  401. /// <summary>
  402. /// Returns a string providing documentation for the specified object.
  403. /// </summary>
  404. public string GetDocumentation(object obj) {
  405. return _ops.GetDocumentation(obj);
  406. }
  407. /// <summary>
  408. /// Returns a list of signatures applicable for calling the specified object in a form displayable to the user.
  409. /// </summary>
  410. public IList<string> GetCallSignatures(object obj) {
  411. return _ops.GetCallSignatures(obj);
  412. }
  413. #endregion
  414. #region Obsolete Operations
  415. /// <summary>
  416. /// Calls the provided object with the given parameters and returns the result.
  417. ///
  418. /// The prefered way of calling objects is to convert the object to a strongly typed delegate
  419. /// using the ConvertTo methods and then invoking that delegate.
  420. /// </summary>
  421. [Obsolete("Use Invoke instead")]
  422. public object Call(object obj, params object[] parameters) {
  423. return _ops.Invoke(obj, parameters);
  424. }
  425. /// <summary>
  426. /// Performs a generic unary operation on the specified target and returns the result.
  427. /// </summary>
  428. [Obsolete]
  429. public object DoOperation(Operators op, object target) {
  430. ExpressionType newOp = GetLinqOp(op);
  431. return _ops.DoOperation<object, object>(newOp, target);
  432. }
  433. /// <summary>
  434. /// Performs a generic unary operation on the strongly typed target and returns the value as the specified type
  435. /// </summary>
  436. [Obsolete("Use ExpressionType overload instead")]
  437. public TResult DoOperation<TTarget, TResult>(Operators op, TTarget target) {
  438. return _ops.DoOperation<TTarget, TResult>(GetLinqOp(op), target);
  439. }
  440. [Obsolete]
  441. private static ExpressionType GetLinqOp(Operators op) {
  442. ExpressionType? newOp = null;
  443. switch (op) {
  444. case Operators.Positive: newOp = ExpressionType.UnaryPlus; break;
  445. case Operators.Negate: newOp = ExpressionType.Negate; break;
  446. case Operators.OnesComplement: newOp = ExpressionType.OnesComplement; break;
  447. case Operators.IsFalse: newOp = ExpressionType.IsFalse; break;
  448. case Operators.Decrement: newOp = ExpressionType.Decrement; break;
  449. case Operators.Increment: newOp = ExpressionType.Increment; break;
  450. default:
  451. throw new InvalidOperationException(String.Format("Unrecognized shared operation: {0}", op));
  452. }
  453. return newOp.Value;
  454. }
  455. /// <summary>
  456. /// Performs modulus of the 1st object by the second object. Throws an exception
  457. /// if the operation cannot be performed.
  458. /// </summary>
  459. [Obsolete("Use Modulo instead")]
  460. public object Modulus(object self, object other) {
  461. return Modulo(self, other);
  462. }
  463. /// <summary>
  464. /// Performs the generic binary operation on the specified targets and returns the result.
  465. /// </summary>
  466. [Obsolete("Use ExpressionType overload instead")]
  467. public object DoOperation(Operators op, object target, object other) {
  468. return _ops.DoOperation<object, object, object>(GetLinqBinaryOp(op), target, other);
  469. }
  470. [Obsolete]
  471. private static ExpressionType GetLinqBinaryOp(Operators op) {
  472. ExpressionType? newOp = null;
  473. switch (op) {
  474. case Operators.Add: newOp = ExpressionType.Add; break;
  475. case Operators.BitwiseAnd: newOp = ExpressionType.And; break;
  476. case Operators.Divide: newOp = ExpressionType.Divide; break;
  477. case Operators.ExclusiveOr: newOp = ExpressionType.ExclusiveOr; break;
  478. case Operators.Mod: newOp = ExpressionType.Modulo; break;
  479. case Operators.Multiply: newOp = ExpressionType.Multiply; break;
  480. case Operators.BitwiseOr: newOp = ExpressionType.Or; break;
  481. case Operators.Power: newOp = ExpressionType.Power; break;
  482. case Operators.RightShift: newOp = ExpressionType.RightShift; break;
  483. case Operators.LeftShift: newOp = ExpressionType.LeftShift; break;
  484. case Operators.Subtract: newOp = ExpressionType.Subtract; break;
  485. case Operators.Equals: newOp = ExpressionType.Equal; break;
  486. case Operators.GreaterThan: newOp = ExpressionType.GreaterThan; break;
  487. case Operators.GreaterThanOrEqual: newOp = ExpressionType.GreaterThanOrEqual; break;
  488. case Operators.LessThan: newOp = ExpressionType.LessThan; break;
  489. case Operators.LessThanOrEqual: newOp = ExpressionType.LessThanOrEqual; break;
  490. case Operators.NotEquals: newOp = ExpressionType.NotEqual; break;
  491. default:
  492. throw new InvalidOperationException(String.Format("Unrecognized shared operation: {0}", op));
  493. }
  494. return newOp.Value;
  495. }
  496. /// <summary>
  497. /// Peforms the generic binary operation on the specified strongly typed targets and returns
  498. /// the strongly typed result.
  499. /// </summary>
  500. [Obsolete]
  501. public TResult DoOperation<TTarget, TOther, TResult>(Operators op, TTarget target, TOther other) {
  502. return _ops.DoOperation<TTarget, TOther, TResult>(GetLinqBinaryOp(op), target, other);
  503. }
  504. #if !SILVERLIGHT
  505. /// <summary>
  506. /// Calls the specified remote object with the specified remote parameters.
  507. ///
  508. /// Though delegates are preferable for calls they may not always be usable for remote objects.
  509. /// </summary>
  510. [Obsolete("Use Invoke instead")]
  511. public ObjectHandle Call(ObjectHandle obj, params ObjectHandle[] parameters) {
  512. return Invoke(obj, parameters);
  513. }
  514. /// <summary>
  515. /// Calls the specified remote object with the local parameters which will be serialized
  516. /// to the remote app domain.
  517. /// </summary>
  518. [Obsolete("Use Invoke instead")]
  519. public ObjectHandle Call(ObjectHandle obj, params object[] parameters) {
  520. return Invoke(obj, parameters);
  521. }
  522. /// <summary>
  523. /// Performs the specified unary operator on the remote object.
  524. /// </summary>
  525. [Obsolete("Use the ExpressionType overload instead")]
  526. public object DoOperation(Operators op, ObjectHandle target) {
  527. return DoOperation(op, GetLocalObject(target));
  528. }
  529. /// <summary>
  530. /// Performs the specified binary operator on the remote object.
  531. /// </summary>
  532. [Obsolete("Use the ExpressionType enum instead")]
  533. public ObjectHandle DoOperation(Operators op, ObjectHandle target, ObjectHandle other) {
  534. return new ObjectHandle(DoOperation(op, GetLocalObject(target), GetLocalObject(other)));
  535. }
  536. /// <summary>
  537. /// Performs modulus on the 1st remote object by the 2nd. Throws an exception if the operation cannot be performed.
  538. /// </summary>
  539. [Obsolete("Use Modulo instead")]
  540. public ObjectHandle Modulus(ObjectHandle self, ObjectHandle other) {
  541. return Modulo(self, other);
  542. }
  543. #endif
  544. #endregion
  545. #pragma warning restore 618
  546. #region Remote APIs
  547. #if !SILVERLIGHT
  548. // ObjectHandle overloads
  549. //
  550. /// <summary>
  551. /// Returns true if the remote object is callable.
  552. /// </summary>
  553. public bool IsCallable([NotNull]ObjectHandle obj) {
  554. return IsCallable(GetLocalObject(obj));
  555. }
  556. /// <summary>
  557. /// Invokes the specified remote object with the specified remote parameters.
  558. ///
  559. /// Though delegates are preferable for calls they may not always be usable for remote objects.
  560. /// </summary>
  561. public ObjectHandle Invoke([NotNull]ObjectHandle obj, params ObjectHandle[] parameters) {
  562. ContractUtils.RequiresNotNull(parameters, "parameters");
  563. return new ObjectHandle(Invoke(GetLocalObject(obj), GetLocalObjects(parameters)));
  564. }
  565. /// <summary>
  566. /// Invokes the specified remote object with the local parameters which will be serialized
  567. /// to the remote app domain.
  568. /// </summary>
  569. public ObjectHandle Invoke([NotNull]ObjectHandle obj, params object[] parameters) {
  570. return new ObjectHandle(Invoke(GetLocalObject(obj), parameters));
  571. }
  572. public ObjectHandle Create([NotNull]ObjectHandle obj, [NotNull]params ObjectHandle[] parameters) {
  573. return new ObjectHandle(CreateInstance(GetLocalObject(obj), GetLocalObjects(parameters)));
  574. }
  575. public ObjectHandle Create([NotNull]ObjectHandle obj, params object[] parameters) {
  576. return new ObjectHandle(CreateInstance(GetLocalObject(obj), parameters));
  577. }
  578. /// <summary>
  579. /// Sets the remote object as a member on the provided remote object.
  580. /// </summary>
  581. public void SetMember([NotNull]ObjectHandle obj, string name, [NotNull]ObjectHandle value) {
  582. SetMember(GetLocalObject(obj), name, GetLocalObject(value));
  583. }
  584. /// <summary>
  585. /// Sets the member name on the remote object obj to value. This overload can be used to avoid
  586. /// boxing and casting of strongly typed members.
  587. /// </summary>
  588. public void SetMember<T>([NotNull]ObjectHandle obj, string name, T value) {
  589. SetMember<T>(GetLocalObject(obj), name, value);
  590. }
  591. /// <summary>
  592. /// Gets the member name on the remote object. Throws an exception if the member is not defined or
  593. /// is write-only.
  594. /// </summary>
  595. public ObjectHandle GetMember([NotNull]ObjectHandle obj, string name) {
  596. return new ObjectHandle(GetMember(GetLocalObject(obj), name));
  597. }
  598. /// <summary>
  599. /// Gets the member name on the remote object. Throws an exception if the member is not defined or
  600. /// is write-only.
  601. /// </summary>
  602. public T GetMember<T>([NotNull]ObjectHandle obj, string name) {
  603. return GetMember<T>(GetLocalObject(obj), name);
  604. }
  605. /// <summary>
  606. /// Gets the member name on the remote object. Returns false if the member is not defined or
  607. /// is write-only.
  608. /// </summary>
  609. public bool TryGetMember([NotNull]ObjectHandle obj, string name, out ObjectHandle value) {
  610. object val;
  611. if (TryGetMember(GetLocalObject(obj), name, out val)) {
  612. value = new ObjectHandle(val);
  613. return true;
  614. }
  615. value = null;
  616. return false;
  617. }
  618. /// <summary>
  619. /// Tests to see if the member name is defined on the remote object.
  620. /// </summary>
  621. public bool ContainsMember([NotNull]ObjectHandle obj, string name) {
  622. return ContainsMember(GetLocalObject(obj), name);
  623. }
  624. /// <summary>
  625. /// Removes the member from the remote object
  626. /// </summary>
  627. public bool RemoveMember([NotNull]ObjectHandle obj, string name) {
  628. return RemoveMember(GetLocalObject(obj), name);
  629. }
  630. /// <summary>
  631. /// Converts the remote object into the specified type returning a handle to
  632. /// the new remote object.
  633. /// </summary>
  634. public ObjectHandle ConvertTo<T>([NotNull]ObjectHandle obj) {
  635. return new ObjectHandle(ConvertTo<T>(GetLocalObject(obj)));
  636. }
  637. /// <summary>
  638. /// Converts the remote object into the specified type returning a handle to
  639. /// the new remote object.
  640. /// </summary>
  641. public ObjectHandle ConvertTo([NotNull]ObjectHandle obj, Type type) {
  642. return new ObjectHandle(ConvertTo(GetLocalObject(obj), type));
  643. }
  644. /// <summary>
  645. /// Converts the remote object into the specified type returning a handle to
  646. /// the new remote object. Returns true if the value can be converted,
  647. /// false if it cannot.
  648. /// </summary>
  649. public bool TryConvertTo<T>([NotNull]ObjectHandle obj, out ObjectHandle result) {
  650. T resultObj;
  651. if (TryConvertTo<T>(GetLocalObject(obj), out resultObj)) {
  652. result = new ObjectHandle(resultObj);
  653. return true;
  654. }
  655. result = null;
  656. return false;
  657. }
  658. /// <summary>
  659. /// Converts the remote object into the specified type returning a handle to
  660. /// the new remote object. Returns true if the value can be converted,
  661. /// false if it cannot.
  662. /// </summary>
  663. public bool TryConvertTo([NotNull]ObjectHandle obj, Type type, out ObjectHandle result) {
  664. object resultObj;
  665. if (TryConvertTo(GetLocalObject(obj), type, out resultObj)) {
  666. result = new ObjectHandle(resultObj);
  667. return true;
  668. }
  669. result = null;
  670. return false;
  671. }
  672. /// <summary>
  673. /// Converts the object obj to the type T including explicit conversions which may lose information.
  674. /// </summary>
  675. public ObjectHandle ExplicitConvertTo<T>([NotNull]ObjectHandle obj) {
  676. return new ObjectHandle(_ops.ExplicitConvertTo<T>(GetLocalObject(obj)));
  677. }
  678. /// <summary>
  679. /// Converts the object obj to the type type including explicit conversions which may lose information.
  680. /// </summary>
  681. public ObjectHandle ExplicitConvertTo([NotNull]ObjectHandle obj, Type type) {
  682. ContractUtils.RequiresNotNull(type, "type");
  683. return new ObjectHandle(_ops.ExplicitConvertTo(GetLocalObject(obj), type));
  684. }
  685. /// <summary>
  686. /// Converts the object obj to the type T including explicit conversions which may lose information.
  687. ///
  688. /// Returns true if the value can be converted, false if it cannot.
  689. /// </summary>
  690. public bool TryExplicitConvertTo<T>([NotNull]ObjectHandle obj, out ObjectHandle result) {
  691. T outp;
  692. bool res = _ops.TryExplicitConvertTo<T>(GetLocalObject(obj), out outp);
  693. if (res) {
  694. result = new ObjectHandle(obj);
  695. } else {
  696. result = null;
  697. }
  698. return res;
  699. }
  700. /// <summary>
  701. /// Converts the object obj to the type type including explicit conversions which may lose information.
  702. ///
  703. /// Returns true if the value can be converted, false if it cannot.
  704. /// </summary>
  705. public bool TryExplicitConvertTo([NotNull]ObjectHandle obj, Type type, out ObjectHandle result) {
  706. object outp;
  707. bool res = _ops.TryExplicitConvertTo(GetLocalObject(obj), type, out outp);
  708. if (res) {
  709. result = new ObjectHandle(obj);
  710. } else {
  711. result = null;
  712. }
  713. return res;
  714. }
  715. /// <summary>
  716. /// Unwraps the remote object and converts it into the specified type before
  717. /// returning it.
  718. /// </summary>
  719. public T Unwrap<T>([NotNull]ObjectHandle obj) {
  720. return ConvertTo<T>(GetLocalObject(obj));
  721. }
  722. /// <summary>
  723. /// Performs the specified unary operator on the remote object.
  724. /// </summary>
  725. public object DoOperation(ExpressionType op, [NotNull]ObjectHandle target) {
  726. return DoOperation(op, GetLocalObject(target));
  727. }
  728. /// <summary>
  729. /// Performs the specified binary operator on the remote object.
  730. /// </summary>
  731. public ObjectHandle DoOperation(ExpressionType op, ObjectHandle target, ObjectHandle other) {
  732. return new ObjectHandle(DoOperation(op, GetLocalObject(target), GetLocalObject(other)));
  733. }
  734. /// <summary>
  735. /// Adds the two remote objects. Throws an exception if the operation cannot be performed.
  736. /// </summary>
  737. public ObjectHandle Add([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  738. return new ObjectHandle(Add(GetLocalObject(self), GetLocalObject(other)));
  739. }
  740. /// <summary>
  741. /// Subtracts the 1st remote object from the second. Throws an exception if the operation cannot be performed.
  742. /// </summary>
  743. public ObjectHandle Subtract([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  744. return new ObjectHandle(Subtract(GetLocalObject(self), GetLocalObject(other)));
  745. }
  746. /// <summary>
  747. /// Raises the 1st remote object to the power of the 2nd. Throws an exception if the operation cannot be performed.
  748. /// </summary>
  749. public ObjectHandle Power([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  750. return new ObjectHandle(Power(GetLocalObject(self), GetLocalObject(other)));
  751. }
  752. /// <summary>
  753. /// Multiplies the two remote objects. Throws an exception if the operation cannot be performed.
  754. /// </summary>
  755. public ObjectHandle Multiply([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  756. return new ObjectHandle(Multiply(GetLocalObject(self), GetLocalObject(other)));
  757. }
  758. /// <summary>
  759. /// Divides the 1st remote object by the 2nd. Throws an exception if the operation cannot be performed.
  760. /// </summary>
  761. public ObjectHandle Divide([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  762. return new ObjectHandle(Divide(GetLocalObject(self), GetLocalObject(other)));
  763. }
  764. /// <summary>
  765. /// Performs modulus on the 1st remote object by the 2nd. Throws an exception if the operation cannot be performed.
  766. /// </summary>
  767. public ObjectHandle Modulo([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  768. return new ObjectHandle(Modulo(GetLocalObject(self), GetLocalObject(other)));
  769. }
  770. /// <summary>
  771. /// Shifts the 1st remote object left by the 2nd remote object. Throws an exception if the operation cannot be performed.
  772. /// </summary>
  773. public ObjectHandle LeftShift([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  774. return new ObjectHandle(LeftShift(GetLocalObject(self), GetLocalObject(other)));
  775. }
  776. /// <summary>
  777. /// Shifts the 1st remote object right by the 2nd remote object. Throws an exception if the operation cannot be performed.
  778. /// </summary>
  779. public ObjectHandle RightShift([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  780. return new ObjectHandle(RightShift(GetLocalObject(self), GetLocalObject(other)));
  781. }
  782. /// <summary>
  783. /// Performs bitwise-and on the two remote objects. Throws an exception if the operation cannot be performed.
  784. /// </summary>
  785. public ObjectHandle BitwiseAnd([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  786. return new ObjectHandle(BitwiseAnd(GetLocalObject(self), GetLocalObject(other)));
  787. }
  788. /// <summary>
  789. /// Performs bitwise-or on the two remote objects. Throws an exception if the operation cannot be performed.
  790. /// </summary>
  791. public ObjectHandle BitwiseOr([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  792. return new ObjectHandle(BitwiseOr(GetLocalObject(self), GetLocalObject(other)));
  793. }
  794. /// <summary>
  795. /// Performs exclusive-or on the two remote objects. Throws an exception if the operation cannot be performed.
  796. /// </summary>
  797. public ObjectHandle ExclusiveOr([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  798. return new ObjectHandle(ExclusiveOr(GetLocalObject(self), GetLocalObject(other)));
  799. }
  800. /// <summary>
  801. /// Compares the two remote objects and returns true if the 1st is less than the 2nd. Throws an exception if the operation cannot be performed.
  802. /// </summary>
  803. public bool LessThan([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  804. return LessThan(GetLocalObject(self), GetLocalObject(other));
  805. }
  806. /// <summary>
  807. /// Compares the two remote objects and returns true if the 1st is greater than the 2nd. Throws an exception if the operation cannot be performed.
  808. /// </summary>
  809. public bool GreaterThan([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  810. return GreaterThan(GetLocalObject(self), GetLocalObject(other));
  811. }
  812. /// <summary>
  813. /// Compares the two remote objects and returns true if the 1st is less than or equal to the 2nd. Throws an exception if the operation cannot be performed.
  814. /// </summary>
  815. public bool LessThanOrEqual([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  816. return LessThanOrEqual(GetLocalObject(self), GetLocalObject(other));
  817. }
  818. /// <summary>
  819. /// Compares the two remote objects and returns true if the 1st is greater than or equal to than the 2nd. Throws an exception if the operation cannot be performed.
  820. /// </summary>
  821. public bool GreaterThanOrEqual([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  822. return GreaterThanOrEqual(GetLocalObject(self), GetLocalObject(other));
  823. }
  824. /// <summary>
  825. /// Compares the two remote objects and returns true if the 1st is equal to the 2nd. Throws an exception if the operation cannot be performed.
  826. /// </summary>
  827. public bool Equal([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  828. return Equal(GetLocalObject(self), GetLocalObject(other));
  829. }
  830. /// <summary>
  831. /// Compares the two remote objects and returns true if the 1st is not equal to the 2nd. Throws an exception if the operation cannot be performed.
  832. /// </summary>
  833. public bool NotEqual([NotNull]ObjectHandle self, [NotNull]ObjectHandle other) {
  834. return NotEqual(GetLocalObject(self), GetLocalObject(other));
  835. }
  836. /// <summary>
  837. /// Returns a string representation of the object in a langauge specific object display format.
  838. /// </summary>
  839. public string Format([NotNull]ObjectHandle obj) {
  840. return Format(GetLocalObject(obj));
  841. }
  842. /// <summary>
  843. /// Returns a list of strings which contain the known members of the remote object.
  844. /// </summary>
  845. public IList<string> GetMemberNames([NotNull]ObjectHandle obj) {
  846. return GetMemberNames(GetLocalObject(obj));
  847. }
  848. /// <summary>
  849. /// Returns a string providing documentation for the specified remote object.
  850. /// </summary>
  851. public string GetDocumentation([NotNull]ObjectHandle obj) {
  852. return GetDocumentation(GetLocalObject(obj));
  853. }
  854. /// <summary>
  855. /// Returns a list of signatures applicable for calling the specified object in a form displayable to the user.
  856. /// </summary>
  857. public IList<string> GetCallSignatures([NotNull]ObjectHandle obj) {
  858. return GetCallSignatures(GetLocalObject(obj));
  859. }
  860. /// <summary>
  861. /// Helper to unwrap an object - in the future maybe we should validate the current app domain.
  862. /// </summary>
  863. private static object GetLocalObject([NotNull]ObjectHandle obj) {
  864. ContractUtils.RequiresNotNull(obj, "obj");
  865. return obj.Unwrap();
  866. }
  867. /// <summary>
  868. /// Helper to unwrap multiple objects
  869. /// </summary>
  870. private static object[] GetLocalObjects(ObjectHandle[] ohs) {
  871. Debug.Assert(ohs != null);
  872. object[] res = new object[ohs.Length];
  873. for (int i = 0; i < res.Length; i++) {
  874. res[i] = GetLocalObject(ohs[i]);
  875. }
  876. return res;
  877. }
  878. #endif
  879. #endregion
  880. #if !SILVERLIGHT
  881. // TODO: Figure out what is the right lifetime
  882. [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  883. public override object InitializeLifetimeService() {
  884. return null;
  885. }
  886. #endif
  887. }
  888. }