// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Linq;
namespace Microsoft.ClearScript.Test
{
[SuppressMessage("ReSharper", "StringLiteralTypo")]
public sealed class DynamicTestObject : DynamicObject
{
private readonly Dictionary memberMap = new Dictionary();
private readonly Dictionary indexMap = new Dictionary();
public int SomeField = 12345;
public string SomeProperty
{
get { return "Bogus"; }
}
public double SomeMethod()
{
return Math.PI;
}
public string SomeMethod(string unused, params object[] args)
{
return string.Join("+", args);
}
public bool DisableInvocation { get; set; }
public bool DisableDynamicMembers { get; set; }
public override bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result)
{
if (args.Length > 0)
{
result = string.Join(" ", args);
return true;
}
return base.TryCreateInstance(binder, args, out result);
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
if (!DisableInvocation && (args.Length > 0))
{
result = string.Join(",", args);
return true;
}
return base.TryInvoke(binder, args, out result);
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if ((binder.Name == "DynamicMethod") && (args.Length > 0))
{
result = string.Join("-", args);
return true;
}
if ((binder.Name == "SomeField") && (args.Length > 0))
{
result = string.Join(".", args);
return true;
}
if ((binder.Name == "SomeProperty") && (args.Length > 0))
{
result = string.Join(":", args);
return true;
}
if ((binder.Name == "SomeMethod") && (args.Length > 0))
{
result = string.Join(";", args);
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (!DisableDynamicMembers && !binder.Name.StartsWith("Z", StringComparison.Ordinal))
{
return memberMap.TryGetValue(binder.Name, out result);
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!DisableDynamicMembers && !binder.Name.StartsWith("Z", StringComparison.Ordinal))
{
memberMap[binder.Name] = value;
return true;
}
return base.TrySetMember(binder, value);
}
public override bool TryDeleteMember(DeleteMemberBinder binder)
{
if (!DisableDynamicMembers && !binder.Name.StartsWith("Z", StringComparison.Ordinal))
{
return memberMap.Remove(binder.Name);
}
return base.TryDeleteMember(binder);
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes.All(index => (index is int) || ((index is string) && !((string)index).StartsWith("Z", StringComparison.Ordinal))))
{
return indexMap.TryGetValue(string.Join(":", indexes), out result);
}
return base.TryGetIndex(binder, indexes, out result);
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (indexes.All(index => (index is int) || ((index is string) && !((string)index).StartsWith("Z", StringComparison.Ordinal))))
{
indexMap[string.Join(":", indexes)] = value;
return true;
}
return base.TrySetIndex(binder, indexes, value);
}
public override bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes)
{
if (indexes.All(index => (index is int) || ((index is string) && !((string)index).StartsWith("Z", StringComparison.Ordinal))))
{
return indexMap.Remove(string.Join(":", indexes));
}
return base.TryDeleteIndex(binder, indexes);
}
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.ReturnType == typeof(int))
{
result = 98765;
return true;
}
if (binder.ReturnType == typeof(string))
{
result = "Booyakasha!";
return true;
}
return base.TryConvert(binder, out result);
}
public override IEnumerable GetDynamicMemberNames()
{
foreach (var name in memberMap.Keys)
{
yield return name;
}
yield return "DynamicMethod";
yield return "SomeField";
yield return "SomeProperty";
yield return "SomeMethod";
}
public override string ToString()
{
return "Super Bass-O-Matic '76";
}
}
}