progress
This commit is contained in:
parent
16e76d6b31
commit
484dbfc9d9
529 changed files with 113694 additions and 0 deletions
182
AspClassic.Scripting/ScopeStorage.cs
Normal file
182
AspClassic.Scripting/ScopeStorage.cs
Normal file
|
@ -0,0 +1,182 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq.Expressions;
|
||||
using AspClassic.Scripting.Utils;
|
||||
|
||||
namespace AspClassic.Scripting;
|
||||
|
||||
public sealed class ScopeStorage : IDynamicMetaObjectProvider
|
||||
{
|
||||
private class Meta : DynamicMetaObject
|
||||
{
|
||||
public new ScopeStorage Value => (ScopeStorage)base.Value;
|
||||
|
||||
public Meta(Expression parameter, ScopeStorage storage)
|
||||
: base(parameter, BindingRestrictions.Empty, storage)
|
||||
{
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
|
||||
{
|
||||
return DynamicTryGetValue(binder.Name, binder.IgnoreCase, binder.FallbackGetMember(this).Expression, (Expression tmp) => tmp);
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
|
||||
{
|
||||
return DynamicTryGetValue(binder.Name, binder.IgnoreCase, binder.FallbackInvokeMember(this, args).Expression, (Expression tmp) => binder.FallbackInvoke(new DynamicMetaObject(tmp, BindingRestrictions.Empty), args, null).Expression);
|
||||
}
|
||||
|
||||
private DynamicMetaObject DynamicTryGetValue(string name, bool ignoreCase, Expression fallback, Func<Expression, Expression> resultOp)
|
||||
{
|
||||
IScopeVariable variable = Value.GetVariable(name, ignoreCase);
|
||||
ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
|
||||
return new DynamicMetaObject(Expression.Block(new ParameterExpression[1] { parameterExpression }, Expression.Condition(Expression.Call(Variable(variable), variable.GetType().GetMethod("TryGetValue"), parameterExpression), ExpressionUtils.Convert(resultOp(parameterExpression), typeof(object)), ExpressionUtils.Convert(fallback, typeof(object)))), BindingRestrictions.GetInstanceRestriction(base.Expression, Value));
|
||||
}
|
||||
|
||||
private static Expression Variable(IScopeVariable variable)
|
||||
{
|
||||
return Expression.Convert(Expression.Property(Expression.Constant(((IWeakReferencable)variable).WeakReference), typeof(WeakReference).GetProperty("Target")), variable.GetType());
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
|
||||
{
|
||||
IScopeVariable variable = Value.GetVariable(binder.Name, binder.IgnoreCase);
|
||||
Expression expression = ExpressionUtils.Convert(value.Expression, typeof(object));
|
||||
return new DynamicMetaObject(Expression.Block(Expression.Call(Variable(variable), variable.GetType().GetMethod("SetValue"), expression), expression), BindingRestrictions.GetInstanceRestriction(base.Expression, Value));
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
|
||||
{
|
||||
IScopeVariable variable = Value.GetVariable(binder.Name, binder.IgnoreCase);
|
||||
return new DynamicMetaObject(Expression.Condition(Expression.Call(Variable(variable), variable.GetType().GetMethod("DeleteValue")), Expression.Default(binder.ReturnType), binder.FallbackDeleteMember(this).Expression), BindingRestrictions.GetInstanceRestriction(base.Expression, Value));
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetDynamicMemberNames()
|
||||
{
|
||||
return Value.GetMemberNames();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, ScopeVariableIgnoreCase> _storage = new Dictionary<string, ScopeVariableIgnoreCase>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public dynamic this[string index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetValue(index, ignoreCase: false);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(index, ignoreCase: false, (object)value);
|
||||
}
|
||||
}
|
||||
|
||||
public dynamic GetValue(string name, bool ignoreCase)
|
||||
{
|
||||
if (GetVariable(name, ignoreCase).TryGetValue(out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
throw new KeyNotFoundException("no value");
|
||||
}
|
||||
|
||||
public bool TryGetValue(string name, bool ignoreCase, out dynamic value)
|
||||
{
|
||||
if (HasVariable(name) && GetVariable(name, ignoreCase).TryGetValue(out var value2))
|
||||
{
|
||||
value = value2;
|
||||
return true;
|
||||
}
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetValue(string name, bool ignoreCase, object value)
|
||||
{
|
||||
GetVariable(name, ignoreCase).SetValue(value);
|
||||
}
|
||||
|
||||
public bool DeleteValue(string name, bool ignoreCase)
|
||||
{
|
||||
if (!HasVariable(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return GetVariable(name, ignoreCase).DeleteValue();
|
||||
}
|
||||
|
||||
public bool HasValue(string name, bool ignoreCase)
|
||||
{
|
||||
if (!HasVariable(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return GetVariable(name, ignoreCase).HasValue;
|
||||
}
|
||||
|
||||
public IScopeVariable GetVariable(string name, bool ignoreCase)
|
||||
{
|
||||
if (ignoreCase)
|
||||
{
|
||||
return GetVariableIgnoreCase(name);
|
||||
}
|
||||
return GetVariable(name);
|
||||
}
|
||||
|
||||
public ScopeVariable GetVariable(string name)
|
||||
{
|
||||
return GetVariableIgnoreCase(name).GetCaseSensitiveStorage(name);
|
||||
}
|
||||
|
||||
public ScopeVariableIgnoreCase GetVariableIgnoreCase(string name)
|
||||
{
|
||||
lock (_storage)
|
||||
{
|
||||
if (!_storage.TryGetValue(name, out var value))
|
||||
{
|
||||
value = (_storage[name] = new ScopeVariableIgnoreCase(name));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<string> GetMemberNames()
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
lock (_storage)
|
||||
{
|
||||
foreach (ScopeVariableIgnoreCase value in _storage.Values)
|
||||
{
|
||||
value.AddNames(list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<KeyValuePair<string, object>> GetItems()
|
||||
{
|
||||
List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();
|
||||
lock (_storage)
|
||||
{
|
||||
foreach (ScopeVariableIgnoreCase value in _storage.Values)
|
||||
{
|
||||
value.AddItems(list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasVariable(string name)
|
||||
{
|
||||
lock (_storage)
|
||||
{
|
||||
return _storage.ContainsKey(name);
|
||||
}
|
||||
}
|
||||
|
||||
public DynamicMetaObject GetMetaObject(Expression parameter)
|
||||
{
|
||||
return new Meta(parameter, this);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue