Options.Extensions.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #nullable enable
  2. using System;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Reflection;
  6. using Jint.Native;
  7. using Jint.Runtime;
  8. using Jint.Runtime.Debugger;
  9. using Jint.Runtime.Interop;
  10. namespace Jint
  11. {
  12. /// <summary>
  13. /// Compatibility layer to allow fluent syntax against options object.
  14. /// </summary>
  15. public static class OptionsExtensions
  16. {
  17. /// <summary>
  18. /// Run the script in strict mode.
  19. /// </summary>
  20. public static Options Strict(this Options options, bool strict = true)
  21. {
  22. options.Strict = strict;
  23. return options;
  24. }
  25. /// <summary>
  26. /// Selects the handling for script <code>debugger</code> statements.
  27. /// </summary>
  28. /// <remarks>
  29. /// The <c>debugger</c> statement can either be ignored (default) trigger debugging at CLR level (e.g. Visual Studio),
  30. /// or trigger a break in Jint's DebugHandler.
  31. /// </remarks>
  32. public static Options DebuggerStatementHandling(this Options options,
  33. DebuggerStatementHandling debuggerStatementHandling)
  34. {
  35. options.Debugger.StatementHandling = debuggerStatementHandling;
  36. return options;
  37. }
  38. /// <summary>
  39. /// Allow to run the script in debug mode.
  40. /// </summary>
  41. public static Options DebugMode(this Options options, bool debugMode = true)
  42. {
  43. options.Debugger.Enabled = debugMode;
  44. return options;
  45. }
  46. /// <summary>
  47. /// Adds a <see cref="IObjectConverter"/> instance to convert CLR types to <see cref="JsValue"/>
  48. /// </summary>
  49. public static Options AddObjectConverter<T>(this Options options) where T : IObjectConverter, new()
  50. {
  51. return AddObjectConverter(options, new T());
  52. }
  53. /// <summary>
  54. /// Adds a <see cref="IObjectConverter"/> instance to convert CLR types to <see cref="JsValue"/>
  55. /// </summary>
  56. public static Options AddObjectConverter(this Options options, IObjectConverter objectConverter)
  57. {
  58. options.Interop.ObjectConverters.Add(objectConverter);
  59. return options;
  60. }
  61. /// <summary>
  62. /// Sets maximum allowed depth of recursion.
  63. /// </summary>
  64. /// <param name="maxRecursionDepth">
  65. /// The allowed depth.
  66. /// a) In case max depth is zero no recursion is allowed.
  67. /// b) In case max depth is equal to n it means that in one scope function can be called no more than n times.
  68. /// </param>
  69. /// <returns>Options instance for fluent syntax</returns>
  70. public static Options LimitRecursion(this Options options, int maxRecursionDepth = 0)
  71. {
  72. options.Constraints.MaxRecursionDepth = maxRecursionDepth;
  73. return options;
  74. }
  75. public static Options Culture(this Options options, CultureInfo cultureInfo)
  76. {
  77. options.Culture = cultureInfo;
  78. return options;
  79. }
  80. public static Options LocalTimeZone(this Options options, TimeZoneInfo timeZoneInfo)
  81. {
  82. options.TimeZone = timeZoneInfo;
  83. return options;
  84. }
  85. public static Options AddExtensionMethods(this Options options, params Type[] types)
  86. {
  87. options.Interop.ExtensionMethodTypes.AddRange(types);
  88. return options;
  89. }
  90. /// <summary>
  91. /// If no known type could be guessed, objects are normally wrapped as an
  92. /// ObjectInstance using class ObjectWrapper. This function can be used to
  93. /// register a handler for a customized handling.
  94. /// </summary>
  95. public static Options SetWrapObjectHandler(this Options options, WrapObjectDelegate wrapObjectHandler)
  96. {
  97. options.Interop.WrapObjectHandler = wrapObjectHandler;
  98. return options;
  99. }
  100. /// <summary>
  101. /// Sets the type converter to use.
  102. /// </summary>
  103. public static Options SetTypeConverter(this Options options, Func<Engine, ITypeConverter> typeConverterFactory)
  104. {
  105. options._configurations.Add(engine => engine.ClrTypeConverter = typeConverterFactory(engine));
  106. return options;
  107. }
  108. /// <summary>
  109. /// Registers a delegate that is called when CLR members are invoked. This allows
  110. /// to change what values are returned for specific CLR objects, or if any value
  111. /// is returned at all.
  112. /// </summary>
  113. /// <param name="accessor">
  114. /// The delegate to invoke for each CLR member. If the delegate
  115. /// returns <c>null</c>, the standard evaluation is performed.
  116. /// </param>
  117. public static Options SetMemberAccessor(this Options options, MemberAccessorDelegate accessor)
  118. {
  119. options.Interop.MemberAccessor = accessor;
  120. return options;
  121. }
  122. /// <summary>
  123. /// Allows scripts to call CLR types directly like <example>System.IO.File</example>
  124. /// </summary>
  125. public static Options AllowClr(this Options options, params Assembly[] assemblies)
  126. {
  127. options.Interop.Enabled = true;
  128. options.Interop.AllowedAssemblies.AddRange(assemblies);
  129. options.Interop.AllowedAssemblies = options.Interop.AllowedAssemblies.Distinct().ToList();
  130. return options;
  131. }
  132. public static Options AllowClrWrite(this Options options, bool allow = true)
  133. {
  134. options.Interop.AllowWrite = allow;
  135. return options;
  136. }
  137. public static Options AllowOperatorOverloading(this Options options, bool allow = true)
  138. {
  139. options.Interop.OperatorOverloadingAllowed = allow;
  140. return options;
  141. }
  142. /// <summary>
  143. /// Exceptions thrown from CLR code are converted to JavaScript errors and
  144. /// can be used in at try/catch statement. By default these exceptions are bubbled
  145. /// to the CLR host and interrupt the script execution.
  146. /// </summary>
  147. public static Options CatchClrExceptions(this Options options)
  148. {
  149. CatchClrExceptions(options, _ => true);
  150. return options;
  151. }
  152. /// <summary>
  153. /// Exceptions that thrown from CLR code are converted to JavaScript errors and
  154. /// can be used in at try/catch statement. By default these exceptions are bubbled
  155. /// to the CLR host and interrupt the script execution.
  156. /// </summary>
  157. public static Options CatchClrExceptions(this Options options, ExceptionHandlerDelegate handler)
  158. {
  159. options.Interop.ExceptionHandler = handler;
  160. return options;
  161. }
  162. public static Options Constraint(this Options options, IConstraint constraint)
  163. {
  164. if (constraint != null)
  165. {
  166. options.Constraints.Constraints.Add(constraint);
  167. }
  168. return options;
  169. }
  170. public static Options WithoutConstraint(this Options options, Predicate<IConstraint> predicate)
  171. {
  172. options.Constraints.Constraints.RemoveAll(predicate);
  173. return options;
  174. }
  175. public static Options RegexTimeoutInterval(this Options options, TimeSpan regexTimeoutInterval)
  176. {
  177. options.Constraints.RegexTimeout = regexTimeoutInterval;
  178. return options;
  179. }
  180. public static Options MaxArraySize(this Options options, uint maxSize)
  181. {
  182. options.Constraints.MaxArraySize = maxSize;
  183. return options;
  184. }
  185. public static Options SetReferencesResolver(this Options options, IReferenceResolver resolver)
  186. {
  187. options.ReferenceResolver = resolver;
  188. return options;
  189. }
  190. public static Options SetTypeResolver(this Options options, TypeResolver resolver)
  191. {
  192. options.Interop.TypeResolver = resolver;
  193. return options;
  194. }
  195. /// <summary>
  196. /// Registers some custom logic to apply on an <see cref="Engine"/> instance when the options
  197. /// are loaded.
  198. /// </summary>
  199. /// <param name="configuration">The action to register.</param>
  200. public static Options Configure(this Options options, Action<Engine> configuration)
  201. {
  202. options._configurations.Add(configuration);
  203. return options;
  204. }
  205. /// <summary>
  206. /// Allows to configure how the host is constructed.
  207. /// </summary>
  208. /// <remarks>
  209. /// Passed Engine instance is still in construction and should not be used during call stage.
  210. /// </remarks>
  211. public static void UseHostFactory<T>(this Options options, Func<Engine, T> factory) where T : Host
  212. {
  213. options.Host.Factory = factory;
  214. }
  215. }
  216. }