Clean up logic of object interpretation in PDT interpreter.
This commit is contained in:
@@ -28,6 +28,10 @@ namespace Cryville.Common.Collections.Generic {
|
|||||||
if (_pairList != null) _pairList.CopyTo(array, index);
|
if (_pairList != null) _pairList.CopyTo(array, index);
|
||||||
else _dictionary.CopyTo(array, index);
|
else _dictionary.CopyTo(array, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsPairCollection(Type type) {
|
||||||
|
return typeof(IPairList<TKey, TValue>).IsAssignableFrom(type) || typeof(IDictionary<TKey, TValue>).IsAssignableFrom(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
internal class PairCollectionDebugView<TKey, TValue> {
|
internal class PairCollectionDebugView<TKey, TValue> {
|
||||||
readonly PairCollection<TKey, TValue> _self;
|
readonly PairCollection<TKey, TValue> _self;
|
||||||
|
@@ -29,6 +29,10 @@ namespace Cryville.Common.Collections {
|
|||||||
if (_pairList != null) _pairList.CopyTo(array, index);
|
if (_pairList != null) _pairList.CopyTo(array, index);
|
||||||
else _dictionary.CopyTo(array, index);
|
else _dictionary.CopyTo(array, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsPairCollection(Type type) {
|
||||||
|
return typeof(IPairList).IsAssignableFrom(type) || typeof(IDictionary).IsAssignableFrom(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
internal class PairCollectionDebugView {
|
internal class PairCollectionDebugView {
|
||||||
readonly PairCollection _self;
|
readonly PairCollection _self;
|
||||||
|
@@ -229,7 +229,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
object InterpretObject(Type type) {
|
object InterpretObject(Type type) {
|
||||||
var result = ReflectionHelper.InvokeEmptyConstructor(type);
|
var result = ReflectionHelper.InvokeEmptyConstructor(type);
|
||||||
bool dictflag = typeof(IDictionary).IsAssignableFrom(type);
|
bool pcflag = PairCollection.IsPairCollection(type);
|
||||||
while (true) {
|
while (true) {
|
||||||
try { ws(); }
|
try { ws(); }
|
||||||
catch (IndexOutOfRangeException) { return result; }
|
catch (IndexOutOfRangeException) { return result; }
|
||||||
@@ -241,69 +241,47 @@ namespace Cryville.Common.Pdt {
|
|||||||
char c = GetChar();
|
char c = GetChar();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '{':
|
case '{':
|
||||||
if (dictflag) {
|
InterpretObjectInternal<ElementListAttribute>(pcflag, type, pkey, result, type => InterpretObject(type));
|
||||||
var ktype = type.GetGenericArguments()[0];
|
|
||||||
var ptype = type.GetGenericArguments()[1];
|
|
||||||
object key = _binder.ChangeType(pkey, ktype, null);
|
|
||||||
object value = InterpretObject(ptype);
|
|
||||||
((IDictionary)result).Add(key, value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MemberInfo prop = null;
|
|
||||||
bool flag = false;
|
|
||||||
if (pkey is string) prop = ReflectionHelper.GetMember(type, (string)pkey);
|
|
||||||
if (prop == null) flag = ReflectionHelper.TryFindMemberWithAttribute<ElementListAttribute>(type, out prop);
|
|
||||||
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
|
||||||
Type ptype = ReflectionHelper.GetMemberType(prop);
|
|
||||||
if (flag) {
|
|
||||||
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
|
||||||
var ktype = ptype.GetGenericArguments()[0];
|
|
||||||
var vtype = ptype.GetGenericArguments()[1];
|
|
||||||
object key = _binder.ChangeType(pkey, ktype, null);
|
|
||||||
object value = InterpretObject(vtype);
|
|
||||||
collection.Add(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else ReflectionHelper.SetValue(prop, result, InterpretObject(ptype));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
case ';':
|
case ';':
|
||||||
var exp = c == ';' ? _emptyexp : GetExp();
|
var exp = c == ';' ? _emptyexp : GetExp();
|
||||||
if (dictflag) {
|
InterpretObjectInternal<PropertyListAttribute>(pcflag, type, pkey, result, type => _binder.ChangeType(exp, type, null));
|
||||||
var ktype = type.GetGenericArguments()[0];
|
|
||||||
var vtype = type.GetGenericArguments()[1];
|
|
||||||
object key = _binder.ChangeType(pkey, ktype, null);
|
|
||||||
object value = _binder.ChangeType(exp, vtype, null);
|
|
||||||
((IDictionary)result).Add(key, value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MemberInfo prop = null;
|
|
||||||
bool flag = false;
|
|
||||||
if (pkey is string) prop = ReflectionHelper.GetMember(type, (string)pkey);
|
|
||||||
if (prop == null) flag = ReflectionHelper.TryFindMemberWithAttribute<PropertyListAttribute>(type, out prop);
|
|
||||||
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
|
||||||
var ptype = ReflectionHelper.GetMemberType(prop);
|
|
||||||
if (flag) {
|
|
||||||
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
|
||||||
var ktype = ptype.GetGenericArguments()[0];
|
|
||||||
var vtype = ptype.GetGenericArguments()[1];
|
|
||||||
object key = _binder.ChangeType(pkey, ktype, null);
|
|
||||||
object value = _binder.ChangeType(exp, vtype, null);
|
|
||||||
collection.Add(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
object value = _binder.ChangeType(exp, ptype, null);
|
|
||||||
ReflectionHelper.SetValue(prop, result, value, _binder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException("Internal error: Invalid key interpretation");
|
throw new InvalidOperationException("Internal error: Invalid key interpretation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void InterpretObjectInternal<T>(bool pcflag, Type type, object pkey, object result, Func<Type, object> vfunc) where T : Attribute {
|
||||||
|
if (pcflag) {
|
||||||
|
using (var collection = new PairCollection(result)) {
|
||||||
|
var ktype = type.GetGenericArguments()[0];
|
||||||
|
var ptype = type.GetGenericArguments()[1];
|
||||||
|
object key = _binder.ChangeType(pkey, ktype, null);
|
||||||
|
object value = vfunc(ptype);
|
||||||
|
collection.Add(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MemberInfo prop = null;
|
||||||
|
bool flag = false;
|
||||||
|
if (pkey is string) prop = ReflectionHelper.GetMember(type, (string)pkey);
|
||||||
|
if (prop == null) flag = ReflectionHelper.TryFindMemberWithAttribute<T>(type, out prop);
|
||||||
|
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||||
|
Type ptype = ReflectionHelper.GetMemberType(prop);
|
||||||
|
if (flag) {
|
||||||
|
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
||||||
|
var ktype = ptype.GetGenericArguments()[0];
|
||||||
|
var vtype = ptype.GetGenericArguments()[1];
|
||||||
|
object key = _binder.ChangeType(pkey, ktype, null);
|
||||||
|
object value = vfunc(vtype);
|
||||||
|
collection.Add(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else ReflectionHelper.SetValue(prop, result, vfunc(ptype), _binder);
|
||||||
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interprets a key from the current position.
|
/// Interprets a key from the current position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Reference in New Issue
Block a user