using System.Globalization; using System.Linq; using System.Reflection; using Jint.Native; using Jint.Runtime; using Jint.Runtime.Debugger; using Jint.Runtime.Interop; using Jint.Runtime.Modules; namespace Jint; /// /// Compatibility layer to allow fluent syntax against options object. /// public static class OptionsExtensions { /// /// Run the script in strict mode. /// public static Options Strict(this Options options, bool strict = true) { options.Strict = strict; return options; } /// /// Selects the handling for script debugger statements. /// /// /// The debugger statement can either be ignored (default) trigger debugging at CLR level (e.g. Visual Studio), /// or trigger a break in Jint's DebugHandler. /// public static Options DebuggerStatementHandling(this Options options, DebuggerStatementHandling debuggerStatementHandling) { options.Debugger.StatementHandling = debuggerStatementHandling; return options; } /// /// Allow to run the script in debug mode. /// public static Options DebugMode(this Options options, bool debugMode = true) { options.Debugger.Enabled = debugMode; return options; } /// /// Set initial step mode. /// public static Options InitialStepMode(this Options options, StepMode initialStepMode = StepMode.None) { options.Debugger.InitialStepMode = initialStepMode; return options; } /// /// Adds a instance to convert CLR types to /// public static Options AddObjectConverter(this Options options) where T : IObjectConverter, new() { return AddObjectConverter(options, new T()); } /// /// Adds a instance to convert CLR types to /// public static Options AddObjectConverter(this Options options, IObjectConverter objectConverter) { options.Interop.ObjectConverters.Add(objectConverter); return options; } /// /// Sets maximum allowed depth of recursion. /// /// Options to modify /// /// The allowed depth. /// a) In case max depth is zero no recursion is allowed. /// b) In case max depth is equal to n it means that in one scope function can be called no more than n times. /// /// Options instance for fluent syntax public static Options LimitRecursion(this Options options, int maxRecursionDepth = 0) { options.Constraints.MaxRecursionDepth = maxRecursionDepth; return options; } public static Options Culture(this Options options, CultureInfo cultureInfo) { options.Culture = cultureInfo; return options; } public static Options LocalTimeZone(this Options options, TimeZoneInfo timeZoneInfo) { options.TimeZone = timeZoneInfo; return options; } /// /// Disables calling 'eval' with custom code and function constructors taking function code as string. /// By default eval and function code parsing is allowed. /// public static Options DisableStringCompilation(this Options options, bool disable = true) { options.Host.StringCompilationAllowed = !disable; return options; } public static Options AddExtensionMethods(this Options options, params Type[] types) { options.Interop.ExtensionMethodTypes.AddRange(types); return options; } /// /// If no known type could be guessed, objects are normally wrapped as an /// ObjectInstance using class ObjectWrapper. This function can be used to /// register a handler for a customized handling. /// public static Options SetWrapObjectHandler(this Options options, Options.WrapObjectDelegate wrapObjectHandler) { options.Interop.WrapObjectHandler = wrapObjectHandler; return options; } /// /// Sets the handler used to build stack traces. This is useful if the code currently /// running was transpiled (eg. TypeScript) and the source map of original code is available. /// public static Options SetBuildCallStackHandler(this Options options, Options.BuildCallStackDelegate buildCallStackHandler) { options.Interop.BuildCallStackHandler = buildCallStackHandler; return options; } /// /// Sets the type converter to use. /// public static Options SetTypeConverter(this Options options, Func typeConverterFactory) { options._configurations.Add(engine => engine.TypeConverter = typeConverterFactory(engine)); return options; } /// /// Registers a delegate that is called when CLR members are invoked. This allows /// to change what values are returned for specific CLR objects, or if any value /// is returned at all. /// /// Options to modify /// /// The delegate to invoke for each CLR member. If the delegate /// returns null, the standard evaluation is performed. /// public static Options SetMemberAccessor(this Options options, Options.MemberAccessorDelegate accessor) { options.Interop.MemberAccessor = accessor; return options; } /// /// Allows scripts to call CLR types directly like System.IO.File /// public static Options AllowClr(this Options options, params Assembly[] assemblies) { options.Interop.Enabled = true; options.Interop.AllowedAssemblies.AddRange(assemblies); options.Interop.AllowedAssemblies = options.Interop.AllowedAssemblies.Distinct().ToList(); return options; } public static Options AllowClrWrite(this Options options, bool allow = true) { options.Interop.AllowWrite = allow; return options; } public static Options AllowOperatorOverloading(this Options options, bool allow = true) { options.Interop.AllowOperatorOverloading = allow; return options; } /// /// Exceptions thrown from CLR code are converted to JavaScript errors and /// can be used in at try/catch statement. By default these exceptions are bubbled /// to the CLR host and interrupt the script execution. /// public static Options CatchClrExceptions(this Options options) { CatchClrExceptions(options, _ => true); return options; } /// /// Exceptions that thrown from CLR code are converted to JavaScript errors and /// can be used in at try/catch statement. By default these exceptions are bubbled /// to the CLR host and interrupt the script execution. /// public static Options CatchClrExceptions(this Options options, Options.ExceptionHandlerDelegate handler) { options.Interop.ExceptionHandler = handler; return options; } public static Options Constraint(this Options options, Constraint constraint) { if (constraint != null) { options.Constraints.Constraints.Add(constraint); } return options; } public static Options WithoutConstraint(this Options options, Predicate predicate) { options.Constraints.Constraints.RemoveAll(predicate); return options; } public static Options RegexTimeoutInterval(this Options options, TimeSpan regexTimeoutInterval) { options.Constraints.RegexTimeout = regexTimeoutInterval; return options; } public static Options MaxArraySize(this Options options, uint maxSize) { options.Constraints.MaxArraySize = maxSize; return options; } public static Options MaxJsonParseDepth(this Options options, int maxDepth) { options.Json.MaxParseDepth = maxDepth; return options; } public static Options SetReferencesResolver(this Options options, IReferenceResolver resolver) { options.ReferenceResolver = resolver; return options; } public static Options SetTypeResolver(this Options options, TypeResolver resolver) { options.Interop.TypeResolver = resolver; return options; } /// /// Registers some custom logic to apply on an instance when the options /// are loaded. /// /// Options to modify /// The action to register. public static Options Configure(this Options options, Action configuration) { options._configurations.Add(configuration); return options; } /// /// Allows to configure how the host is constructed. /// /// /// Passed Engine instance is still in construction and should not be used during call stage. /// public static Options UseHostFactory(this Options options, Func factory) where T : Host { options.Host.Factory = factory; return options; } /// /// Enables module loading in the engine via the 'require' function. By default there's no sand-boxing and /// you need to trust the script loading the modules not doing bad things. /// public static Options EnableModules(this Options options, string basePath, bool restrictToBasePath = true) { return EnableModules(options, new DefaultModuleLoader(basePath, restrictToBasePath)); } /// /// Enables module loading using a custom loader implementation. /// public static Options EnableModules(this Options options, IModuleLoader moduleLoader) { options.Modules.ModuleLoader = moduleLoader; return options; } }