progress
This commit is contained in:
parent
16e76d6b31
commit
484dbfc9d9
529 changed files with 113694 additions and 0 deletions
198
AspClassic.Scripting/Runtime/Scope.cs
Normal file
198
AspClassic.Scripting/Runtime/Scope.cs
Normal file
|
@ -0,0 +1,198 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq.Expressions;
|
||||
using AspClassic.Scripting.Utils;
|
||||
|
||||
namespace AspClassic.Scripting.Runtime;
|
||||
|
||||
public sealed class Scope : IDynamicMetaObjectProvider
|
||||
{
|
||||
internal sealed class MetaScope : DynamicMetaObject
|
||||
{
|
||||
private DynamicMetaObject StorageMetaObject => DynamicMetaObject.Create(Value._storage, StorageExpression);
|
||||
|
||||
private MemberExpression StorageExpression => Expression.Property(Expression.Convert(base.Expression, typeof(Scope)), typeof(Scope).GetProperty("Storage"));
|
||||
|
||||
public new Scope Value => (Scope)base.Value;
|
||||
|
||||
public MetaScope(Expression parameter, Scope scope)
|
||||
: base(parameter, BindingRestrictions.Empty, scope)
|
||||
{
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
|
||||
{
|
||||
return Restrict(binder.Bind(StorageMetaObject, DynamicMetaObject.EmptyMetaObjects));
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
|
||||
{
|
||||
return Restrict(binder.Bind(StorageMetaObject, args));
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
|
||||
{
|
||||
return Restrict(binder.Bind(StorageMetaObject, new DynamicMetaObject[1] { value }));
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
|
||||
{
|
||||
return Restrict(binder.Bind(StorageMetaObject, DynamicMetaObject.EmptyMetaObjects));
|
||||
}
|
||||
|
||||
private DynamicMetaObject Restrict(DynamicMetaObject result)
|
||||
{
|
||||
if (base.Expression.Type == typeof(Scope))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return new DynamicMetaObject(result.Expression, BindingRestrictions.GetTypeRestriction(base.Expression, typeof(Scope)).Merge(result.Restrictions));
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetDynamicMemberNames()
|
||||
{
|
||||
return StorageMetaObject.GetDynamicMemberNames();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AttributesAdapter : IDynamicMetaObjectProvider
|
||||
{
|
||||
internal sealed class Meta : DynamicMetaObject
|
||||
{
|
||||
public new AttributesAdapter Value => (AttributesAdapter)base.Value;
|
||||
|
||||
public Meta(Expression parameter, AttributesAdapter storage)
|
||||
: base(parameter, BindingRestrictions.Empty, storage)
|
||||
{
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
|
||||
{
|
||||
return DynamicTryGetMember(binder.Name, binder.FallbackGetMember(this).Expression, (Expression tmp) => tmp);
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
|
||||
{
|
||||
return DynamicTryGetMember(binder.Name, binder.FallbackInvokeMember(this, args).Expression, (Expression tmp) => binder.FallbackInvoke(new DynamicMetaObject(tmp, BindingRestrictions.Empty), args, null).Expression);
|
||||
}
|
||||
|
||||
private DynamicMetaObject DynamicTryGetMember(string name, Expression fallback, Func<Expression, Expression> resultOp)
|
||||
{
|
||||
ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
|
||||
return new DynamicMetaObject(Expression.Block(new ParameterExpression[1] { parameterExpression }, Expression.Condition(Expression.NotEqual(Expression.Assign(parameterExpression, Expression.Invoke(Expression.Constant(new Func<object, SymbolId, object>(TryGetMember)), base.Expression, Expression.Constant(SymbolTable.StringToId(name)))), Expression.Constant(_getFailed)), ExpressionUtils.Convert(resultOp(parameterExpression), typeof(object)), ExpressionUtils.Convert(fallback, typeof(object)))), GetRestrictions());
|
||||
}
|
||||
|
||||
private BindingRestrictions GetRestrictions()
|
||||
{
|
||||
return BindingRestrictions.GetTypeRestriction(base.Expression, typeof(AttributesAdapter));
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
|
||||
{
|
||||
return new DynamicMetaObject(Expression.Block(Expression.Invoke(Expression.Constant(new Action<object, SymbolId, object>(TrySetMember)), base.Expression, Expression.Constant(SymbolTable.StringToId(binder.Name)), Expression.Convert(value.Expression, typeof(object))), value.Expression), GetRestrictions());
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
|
||||
{
|
||||
return new DynamicMetaObject(Expression.Condition(Expression.Invoke(Expression.Constant(new Func<object, SymbolId, bool>(TryDeleteMember)), base.Expression, Expression.Constant(SymbolTable.StringToId(binder.Name))), Expression.Default(binder.ReturnType), binder.FallbackDeleteMember(this).Expression), GetRestrictions());
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetDynamicMemberNames()
|
||||
{
|
||||
foreach (object o in Value._data.Keys)
|
||||
{
|
||||
if (o is string)
|
||||
{
|
||||
yield return (string)o;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IAttributesCollection _data;
|
||||
|
||||
public AttributesAdapter(IAttributesCollection data)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
private static object TryGetMember(object adapter, SymbolId name)
|
||||
{
|
||||
if (((AttributesAdapter)adapter)._data.TryGetValue(name, out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return _getFailed;
|
||||
}
|
||||
|
||||
private static void TrySetMember(object adapter, SymbolId name, object value)
|
||||
{
|
||||
((AttributesAdapter)adapter)._data[name] = value;
|
||||
}
|
||||
|
||||
private static bool TryDeleteMember(object adapter, SymbolId name)
|
||||
{
|
||||
return ((AttributesAdapter)adapter)._data.Remove(name);
|
||||
}
|
||||
|
||||
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
|
||||
{
|
||||
return new Meta(parameter, this);
|
||||
}
|
||||
}
|
||||
|
||||
private ScopeExtension[] _extensions;
|
||||
|
||||
private readonly IDynamicMetaObjectProvider _storage;
|
||||
|
||||
private static readonly object _getFailed = new object();
|
||||
|
||||
public dynamic Storage => _storage;
|
||||
|
||||
public Scope()
|
||||
{
|
||||
_extensions = ScopeExtension.EmptyArray;
|
||||
_storage = new ScopeStorage();
|
||||
}
|
||||
|
||||
[Obsolete("IAttributesCollection is obsolete, use Scope(IDynamicMetaObjectProvider) overload instead")]
|
||||
public Scope(IAttributesCollection dictionary)
|
||||
{
|
||||
_extensions = ScopeExtension.EmptyArray;
|
||||
_storage = new AttributesAdapter(dictionary);
|
||||
}
|
||||
|
||||
public Scope(IDynamicMetaObjectProvider storage)
|
||||
{
|
||||
_extensions = ScopeExtension.EmptyArray;
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public ScopeExtension GetExtension(ContextId languageContextId)
|
||||
{
|
||||
if (languageContextId.Id >= _extensions.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _extensions[languageContextId.Id];
|
||||
}
|
||||
|
||||
public ScopeExtension SetExtension(ContextId languageContextId, ScopeExtension extension)
|
||||
{
|
||||
ContractUtils.RequiresNotNull(extension, "extension");
|
||||
lock (_extensions)
|
||||
{
|
||||
if (languageContextId.Id >= _extensions.Length)
|
||||
{
|
||||
Array.Resize(ref _extensions, languageContextId.Id + 1);
|
||||
}
|
||||
return _extensions[languageContextId.Id] ?? (_extensions[languageContextId.Id] = extension);
|
||||
}
|
||||
}
|
||||
|
||||
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
|
||||
{
|
||||
return new MetaScope(parameter, this);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue