aspclassic-core/AspClassic.VBScript/Binders/VBScriptSetIndexBinder.cs
Jelle Luteijn 484dbfc9d9 progress
2022-05-15 11:19:49 +02:00

80 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
//using System.Text;
using System.Reflection;
using System.Dynamic;
#if USE35
using AspClassic.Scripting.Ast;
using AspClassic.Scripting.ComInterop;
#else
using System.Linq;
using System.Linq.Expressions;
using AspClassic.Scripting.ComInterop;
#endif
using Debug = System.Diagnostics.Debug;
using Dlrsoft.VBScript.Runtime;
namespace Dlrsoft.VBScript.Binders
{
public class VBScriptSetIndexBinder : SetIndexBinder
{
public VBScriptSetIndexBinder(CallInfo callinfo)
: base(callinfo)
{
}
public override DynamicMetaObject FallbackSetIndex(
DynamicMetaObject target, DynamicMetaObject[] indexes,
DynamicMetaObject value, DynamicMetaObject errorSuggestion)
{
#if !SILVERLIGHT
// First try COM binding.
DynamicMetaObject result;
if (ComBinder.TryBindSetIndex(this, target, indexes, value, out result))
{
return result;
}
# endif
// Defer if any object has no value so that we evaulate their
// Expressions and nest a CallSite for the InvokeMember.
if (!target.HasValue || indexes.Any((a) => !a.HasValue) ||
!value.HasValue)
{
var deferArgs = new DynamicMetaObject[indexes.Length + 2];
for (int i = 0; i < indexes.Length; i++)
{
deferArgs[i + 1] = indexes[i];
}
deferArgs[0] = target;
deferArgs[indexes.Length + 1] = value;
return Defer(deferArgs);
}
// Find our own binding.
Expression valueExpr = value.Expression;
//we convert a value of TypeModel to Type.
if (value.LimitType == typeof(TypeModel))
{
valueExpr = RuntimeHelpers.GetRuntimeTypeMoFromModel(value).Expression;
}
Debug.Assert(target.HasValue && target.LimitType != typeof(Array));
Expression setIndexExpr;
Expression indexingExpr = RuntimeHelpers.GetIndexingExpression(
target, indexes);
if (valueExpr.Type != indexingExpr.Type && !indexingExpr.Type.IsAssignableFrom(valueExpr.Type))
{
valueExpr = RuntimeHelpers.ConvertExpression(valueExpr, indexingExpr.Type);
}
setIndexExpr = Expression.Assign(indexingExpr, valueExpr);
//TODO review the restriction because the value may be important for proper conversion
//Also need to handle the null value
BindingRestrictions restrictions =
RuntimeHelpers.GetTargetArgsRestrictions(target, indexes, false);
return new DynamicMetaObject(
RuntimeHelpers.EnsureObjectResult(setIndexExpr),
restrictions);
}
}
}