/* ****************************************************************************
*
* 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;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Dynamic;
using Microsoft.Scripting.Actions;
using Microsoft.Scripting.Utils;
using System.Threading;
namespace Microsoft.Scripting.Runtime {
[Serializable]
public class MissingTypeException : Exception {
public MissingTypeException() {
}
public MissingTypeException(string name)
: this(name, null) {
}
public MissingTypeException(string name, Exception e) :
base(Strings.MissingType(name), e) {
}
#if !SILVERLIGHT // SerializationInfo
protected MissingTypeException(SerializationInfo info, StreamingContext context) : base(info, context) { }
#endif
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable")] // TODO: fix
public sealed class ScriptDomainManager {
private readonly DynamicRuntimeHostingProvider _hostingProvider;
private readonly SharedIO _sharedIO;
// last id assigned to a language context:
private int _lastContextId;
private ScopeAttributesWrapper _scopeWrapper;
private Scope _globals;
private readonly DlrConfiguration _configuration;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
public PlatformAdaptationLayer Platform {
get {
PlatformAdaptationLayer result = _hostingProvider.PlatformAdaptationLayer;
if (result == null) {
throw new InvalidImplementationException();
}
return result;
}
}
public SharedIO SharedIO {
get { return _sharedIO; }
}
public DynamicRuntimeHostingProvider Host {
get { return _hostingProvider; }
}
public DlrConfiguration Configuration {
get { return _configuration; }
}
public ScriptDomainManager(DynamicRuntimeHostingProvider hostingProvider, DlrConfiguration configuration) {
ContractUtils.RequiresNotNull(hostingProvider, "hostingProvider");
ContractUtils.RequiresNotNull(configuration, "configuration");
configuration.Freeze();
_hostingProvider = hostingProvider;
_configuration = configuration;
_sharedIO = new SharedIO();
// create the initial default scope
_scopeWrapper = new ScopeAttributesWrapper(this);
_globals = new Scope(_scopeWrapper);
}
#region Language Registration
internal ContextId GenerateContextId() {
return new ContextId(Interlocked.Increment(ref _lastContextId));
}
public LanguageContext GetLanguage(Type providerType) {
ContractUtils.RequiresNotNull(providerType, "providerType");
return GetLanguageByTypeName(providerType.AssemblyQualifiedName);
}
public LanguageContext GetLanguageByTypeName(string providerAssemblyQualifiedTypeName) {
ContractUtils.RequiresNotNull(providerAssemblyQualifiedTypeName, "providerAssemblyQualifiedTypeName");
var aqtn = AssemblyQualifiedTypeName.ParseArgument(providerAssemblyQualifiedTypeName, "providerAssemblyQualifiedTypeName");
LanguageContext language;
if (!_configuration.TryLoadLanguage(this, aqtn, out language)) {
throw Error.UnknownLanguageProviderType();
}
return language;
}
public bool TryGetLanguage(string languageName, out LanguageContext language) {
ContractUtils.RequiresNotNull(languageName, "languageName");
return _configuration.TryLoadLanguage(this, languageName, false, out language);
}
public LanguageContext GetLanguageByName(string languageName) {
LanguageContext language;
if (!TryGetLanguage(languageName, out language)) {
throw new ArgumentException(String.Format("Unknown language name: '{0}'", languageName));
}
return language;
}
public bool TryGetLanguageByFileExtension(string fileExtension, out LanguageContext language) {
ContractUtils.RequiresNotEmpty(fileExtension, "fileExtension");
return _configuration.TryLoadLanguage(this, DlrConfiguration.NormalizeExtension(fileExtension), true, out language);
}
public LanguageContext GetLanguageByExtension(string fileExtension) {
LanguageContext language;
if (!TryGetLanguageByFileExtension(fileExtension, out language)) {
throw new ArgumentException(String.Format("Unknown file extension: '{0}'", fileExtension));
}
return language;
}
#endregion
///
/// A collection of environment variables.
///
public Scope Globals {
get {
return _globals;
}
}
public void SetGlobalsDictionary(IAttributesCollection dictionary) {
ContractUtils.RequiresNotNull(dictionary, "dictionary");
_scopeWrapper.Dict = dictionary;
}
public event EventHandler AssemblyLoaded;
public bool LoadAssembly(Assembly assembly) {
ContractUtils.RequiresNotNull(assembly, "assembly");
if (_scopeWrapper.LoadAssembly(assembly)) {
// only deliver the event if we've never added the assembly before
EventHandler assmLoaded = AssemblyLoaded;
if (assmLoaded != null) {
assmLoaded(this, new AssemblyLoadedEventArgs(assembly));
}
return true;
}
return false;
}
#region ScopeAttributesWrapper
private class ScopeAttributesWrapper : IAttributesCollection {
private IAttributesCollection _dict = new SymbolDictionary();
private readonly TopNamespaceTracker _tracker;
public ScopeAttributesWrapper(ScriptDomainManager manager) {
_tracker = new TopNamespaceTracker(manager);
}
public IAttributesCollection Dict {
set {
Assert.NotNull(_dict);
_dict = value;
}
}
public bool LoadAssembly(Assembly asm) {
return _tracker.LoadAssembly(asm);
}
public List GetLoadedAssemblies() {
return _tracker._packageAssemblies;
}
#region IAttributesCollection Members
public void Add(SymbolId name, object value) {
_dict[name] = value;
}
public bool TryGetValue(SymbolId name, out object value) {
if (_dict.TryGetValue(name, out value)) {
return true;
}
value = _tracker.TryGetPackageAny(name);
return value != null;
}
public bool Remove(SymbolId name) {
return _dict.Remove(name);
}
public bool ContainsKey(SymbolId name) {
return _dict.ContainsKey(name) || _tracker.TryGetPackageAny(name) != null;
}
public object this[SymbolId name] {
get {
object value;
if (TryGetValue(name, out value)) {
return value;
}
throw new KeyNotFoundException();
}
set {
Add(name, value);
}
}
public IDictionary SymbolAttributes {
get { return _dict.SymbolAttributes; }
}
public void AddObjectKey(object name, object value) {
_dict.AddObjectKey(name, value);
}
public bool TryGetObjectValue(object name, out object value) {
return _dict.TryGetObjectValue(name, out value);
}
public bool RemoveObjectKey(object name) {
return _dict.RemoveObjectKey(name);
}
public bool ContainsObjectKey(object name) {
return _dict.ContainsObjectKey(name);
}
public IDictionary