/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System; using System.Collections.Generic; using Microsoft.Scripting.Runtime; using Microsoft.Scripting.Utils; using System.Reflection; using System.IO; using System.Collections.ObjectModel; namespace Microsoft.Scripting.Hosting { /// /// Stores information needed to setup a ScriptRuntime /// [Serializable] public sealed class ScriptRuntimeSetup { // host specification: private Type _hostType; private IList _hostArguments; // languages available in the runtime: private IList _languageSetups; // DLR options: private bool _debugMode; private bool _privateBinding; // common language options: private IDictionary _options; // true if the ScriptRuntimeSetup is no longer mutable because it's been // used to start a ScriptRuntime private bool _frozen; public ScriptRuntimeSetup() { _languageSetups = new List(); _options = new Dictionary(); _hostType = typeof(ScriptHost); _hostArguments = ArrayUtils.EmptyObjects; } /// /// The list of language setup information for languages to load into /// the runtime /// public IList LanguageSetups { get { return _languageSetups; } } /// /// Indicates that the script runtime is in debug mode. /// This means: /// /// 1) Symbols are emitted for debuggable methods (methods associated with SourceUnit). /// 2) Debuggable methods are emitted to non-collectable types (this is due to CLR limitations on dynamic method debugging). /// 3) JIT optimization is disabled for all methods /// 4) Languages may disable optimizations based on this value. /// public bool DebugMode { get { return _debugMode; } set { CheckFrozen(); _debugMode = value; } } /// /// Ignore CLR visibility checks /// public bool PrivateBinding { get { return _privateBinding; } set { CheckFrozen(); _privateBinding = value; } } /// /// Can be any derived class of ScriptHost. When set, it allows the /// host to override certain methods to control behavior of the runtime /// public Type HostType { get { return _hostType; } set { ContractUtils.RequiresNotNull(value, "value"); ContractUtils.Requires(typeof(ScriptHost).IsAssignableFrom(value), "value", "Must be ScriptHost or a derived type of ScriptHost"); CheckFrozen(); _hostType = value; } } /// /// Option names are case-sensitive. /// public IDictionary Options { get { return _options; } } /// /// Arguments passed to the host type when it is constructed /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public IList HostArguments { get { return _hostArguments; } set { ContractUtils.RequiresNotNull(value, "value"); CheckFrozen(); _hostArguments = value; } } internal DlrConfiguration ToConfiguration() { ContractUtils.Requires(_languageSetups.Count > 0, "ScriptRuntimeSetup must have at least one LanguageSetup"); // prepare ReadOnlyCollection setups = new ReadOnlyCollection(ArrayUtils.MakeArray(_languageSetups)); var hostArguments = new ReadOnlyCollection(ArrayUtils.MakeArray(_hostArguments)); var options = new ReadOnlyDictionary(new Dictionary(_options)); var config = new DlrConfiguration(_debugMode, _privateBinding, options); // validate foreach (var language in setups) { config.AddLanguage( language.TypeName, language.DisplayName, language.Names, language.FileExtensions, language.Options ); } // commit _languageSetups = setups; _options = options; _hostArguments = hostArguments; Freeze(setups); return config; } private void Freeze(ReadOnlyCollection setups) { foreach (var language in setups) { language.Freeze(); } _frozen = true; } private void CheckFrozen() { if (_frozen) { throw new InvalidOperationException("Cannot modify ScriptRuntimeSetup after it has been used to create a ScriptRuntime"); } } /// /// Reads setup from .NET configuration system (.config files). /// If there is no configuration available returns an empty setup. /// public static ScriptRuntimeSetup ReadConfiguration() { #if SILVERLIGHT return new ScriptRuntimeSetup(); #else var setup = new ScriptRuntimeSetup(); Configuration.Section.LoadRuntimeSetup(setup, null); return setup; #endif } #if !SILVERLIGHT /// /// Reads setup from a specified XML stream. /// public static ScriptRuntimeSetup ReadConfiguration(Stream configFileStream) { ContractUtils.RequiresNotNull(configFileStream, "configFileStream"); var setup = new ScriptRuntimeSetup(); Configuration.Section.LoadRuntimeSetup(setup, configFileStream); return setup; } /// /// Reads setup from a specified XML file. /// public static ScriptRuntimeSetup ReadConfiguration(string configFilePath) { ContractUtils.RequiresNotNull(configFilePath, "configFilePath"); using (var stream = File.OpenRead(configFilePath)) { return ReadConfiguration(stream); } } #endif } }