123 lines
4.0 KiB
C#
123 lines
4.0 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using Upsilon.BaseTypes.Number;
|
|
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
|
using Upsilon.BoundTypes;
|
|
using Upsilon.Evaluator;
|
|
using Upsilon.Text;
|
|
|
|
namespace Upsilon.BaseTypes.UserData
|
|
{
|
|
internal class DictionaryUserData : ScriptType, IUserData, ILengthType, IIterable
|
|
{
|
|
public IDictionary Dictionary { get; }
|
|
private string BoundTypeName { get; }
|
|
|
|
public DictionaryUserData(IDictionary dictionary)
|
|
{
|
|
Dictionary = dictionary;
|
|
var type = dictionary.GetType();
|
|
var generics = type.GetGenericArguments();
|
|
if (generics.Length == 2)
|
|
{
|
|
var keyType = generics[0];
|
|
var valueType = generics[1];
|
|
var boundKeyType = BoundTypeHandler.GetTypeName(keyType);
|
|
var boundValueType = BoundTypeHandler.GetTypeName(valueType);
|
|
var boundKey = boundKeyType == null
|
|
? new UndefinedUserDataTypeContainer(keyType)
|
|
: new TypeContainer(boundKeyType);
|
|
var boundValue = boundValueType == null
|
|
? new UndefinedUserDataTypeContainer(valueType)
|
|
: new TypeContainer(boundValueType);
|
|
Type = new CompositeTypeContainer(new[] {boundKey, boundValue}.ToImmutableArray());
|
|
}
|
|
else
|
|
{
|
|
BoundTypeName = BoundTypeHandler.GetTypeName(type);
|
|
Type = BoundTypeName == null ? new UndefinedUserDataTypeContainer(type) : new TypeContainer(BoundTypeName);
|
|
}
|
|
}
|
|
|
|
public ScriptType Get(Diagnostics diagnostics, TextSpan span, ScriptType index, EvaluationScope scope)
|
|
{
|
|
var key = index.ToCSharpObject();
|
|
if (Dictionary.Contains(key))
|
|
{
|
|
return Dictionary[key].ToScriptType();
|
|
}
|
|
//TODO: log error
|
|
return new ScriptNull();
|
|
}
|
|
|
|
public void Set(Diagnostics diagnostics, TextSpan span, ScriptType index, ScriptType value)
|
|
{
|
|
var key = index.ToCSharpObject();
|
|
if (Dictionary.Contains(key))
|
|
{
|
|
Dictionary[key] = value.ToCSharpObject();
|
|
}
|
|
else
|
|
{
|
|
Dictionary.Add(key, value.ToCSharpObject());
|
|
}
|
|
}
|
|
|
|
public override TypeContainer Type { get; }
|
|
public override object ToCSharpObject()
|
|
{
|
|
return Dictionary;
|
|
}
|
|
|
|
public override System.Type GetCSharpType()
|
|
{
|
|
return Dictionary.GetType();
|
|
}
|
|
|
|
public ScriptNumberLong Length()
|
|
{
|
|
return new ScriptNumberLong(Dictionary.Count);
|
|
}
|
|
|
|
protected bool Equals(DictionaryUserData other)
|
|
{
|
|
return Dictionary.Equals(other.Dictionary);
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (ReferenceEquals(null, obj)) return false;
|
|
if (ReferenceEquals(this, obj)) return true;
|
|
if (obj.GetType() == Dictionary.GetType())
|
|
{
|
|
return Dictionary.Equals(obj);
|
|
}
|
|
if (obj.GetType() != this.GetType()) return false;
|
|
return Equals((DictionaryUserData) obj);
|
|
}
|
|
|
|
public ScriptType GetValueFromIndex(ScriptType index)
|
|
{
|
|
return Dictionary[index.ToCSharpObject()].ToScriptType();
|
|
}
|
|
|
|
public IEnumerator<ScriptType> GetScriptEnumerator()
|
|
{
|
|
return (from object key in Dictionary.Keys
|
|
select key.ToScriptType()).GetEnumerator();
|
|
}
|
|
|
|
public bool Contains(ScriptType obj)
|
|
{
|
|
var cSharpObj = obj.ToCSharpObject();
|
|
return Dictionary.Contains(cSharpObj);
|
|
}
|
|
|
|
public void Delete(ScriptType key)
|
|
{
|
|
Dictionary.Remove(key.ToCSharpObject());
|
|
}
|
|
}
|
|
} |