aspclassic-core/AspClassic.Scripting/Hosting/LanguageSetup.cs
Jelle Luteijn 484dbfc9d9 progress
2022-05-15 11:19:49 +02:00

186 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using AspClassic.Scripting.Utils;
namespace AspClassic.Scripting.Hosting;
[Serializable]
public sealed class LanguageSetup
{
private string _typeName;
private string _displayName;
private IList<string> _names;
private IList<string> _fileExtensions;
private IDictionary<string, object> _options;
private bool _frozen;
private bool? _interpretedMode;
private bool? _exceptionDetail;
private bool? _perfStats;
private bool? _noAdaptiveCompilation;
public string TypeName
{
get
{
return _typeName;
}
set
{
ContractUtils.RequiresNotEmpty(value, "value");
CheckFrozen();
_typeName = value;
}
}
public string DisplayName
{
get
{
return _displayName;
}
set
{
ContractUtils.RequiresNotNull(value, "value");
CheckFrozen();
_displayName = value;
}
}
public IList<string> Names => _names;
public IList<string> FileExtensions => _fileExtensions;
public IDictionary<string, object> Options => _options;
[Obsolete("This option is ignored")]
public bool InterpretedMode
{
get
{
return GetCachedOption("InterpretedMode", ref _interpretedMode);
}
set
{
CheckFrozen();
Options["InterpretedMode"] = value;
}
}
[Obsolete("Use Options[\"NoAdaptiveCompilation\"] instead.")]
public bool NoAdaptiveCompilation
{
get
{
return GetCachedOption("NoAdaptiveCompilation", ref _noAdaptiveCompilation);
}
set
{
CheckFrozen();
Options["NoAdaptiveCompilation"] = value;
}
}
public bool ExceptionDetail
{
get
{
return GetCachedOption("ExceptionDetail", ref _exceptionDetail);
}
set
{
CheckFrozen();
Options["ExceptionDetail"] = value;
}
}
[Obsolete("Use Options[\"PerfStats\"] instead.")]
public bool PerfStats
{
get
{
return GetCachedOption("PerfStats", ref _perfStats);
}
set
{
CheckFrozen();
Options["PerfStats"] = value;
}
}
public LanguageSetup(string typeName)
: this(typeName, "", ArrayUtils.EmptyStrings, ArrayUtils.EmptyStrings)
{
}
public LanguageSetup(string typeName, string displayName)
: this(typeName, displayName, ArrayUtils.EmptyStrings, ArrayUtils.EmptyStrings)
{
}
public LanguageSetup(string typeName, string displayName, IEnumerable<string> names, IEnumerable<string> fileExtensions)
{
ContractUtils.RequiresNotEmpty(typeName, "typeName");
ContractUtils.RequiresNotNull(displayName, "displayName");
ContractUtils.RequiresNotNull(names, "names");
ContractUtils.RequiresNotNull(fileExtensions, "fileExtensions");
_typeName = typeName;
_displayName = displayName;
_names = new List<string>(names);
_fileExtensions = new List<string>(fileExtensions);
_options = new Dictionary<string, object>();
}
public T GetOption<T>(string name, T defaultValue)
{
if (_options != null && _options.TryGetValue(name, out var value))
{
if (value is T)
{
return (T)value;
}
return (T)Convert.ChangeType(value, typeof(T), Thread.CurrentThread.CurrentCulture);
}
return defaultValue;
}
private bool GetCachedOption(string name, ref bool? storage)
{
if (storage.HasValue)
{
return storage.Value;
}
if (_frozen)
{
storage = GetOption(name, defaultValue: false);
return storage.Value;
}
return GetOption(name, defaultValue: false);
}
internal void Freeze()
{
_frozen = true;
_names = new ReadOnlyCollection<string>(ArrayUtils.MakeArray(_names));
_fileExtensions = new ReadOnlyCollection<string>(ArrayUtils.MakeArray(_fileExtensions));
_options = new AspClassic.Scripting.Utils.ReadOnlyDictionary<string, object>(new Dictionary<string, object>(_options));
}
private void CheckFrozen()
{
if (_frozen)
{
throw new InvalidOperationException("Cannot modify LanguageSetup after it has been used to create a ScriptRuntime");
}
}
}