PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Runtime/Microsoft.Scripting/Hosting/ObjectOperations.cs

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