diff --git a/Assets/Cryville/Common/Collections/Generic/PairCollection.cs b/Assets/Cryville/Common/Collections/Generic/PairCollection.cs index 0dab6b2..01521e8 100644 --- a/Assets/Cryville/Common/Collections/Generic/PairCollection.cs +++ b/Assets/Cryville/Common/Collections/Generic/PairCollection.cs @@ -28,6 +28,10 @@ namespace Cryville.Common.Collections.Generic { if (_pairList != null) _pairList.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 { readonly PairCollection _self; diff --git a/Assets/Cryville/Common/Collections/PairCollection.cs b/Assets/Cryville/Common/Collections/PairCollection.cs index 780e8a4..8051b72 100644 --- a/Assets/Cryville/Common/Collections/PairCollection.cs +++ b/Assets/Cryville/Common/Collections/PairCollection.cs @@ -29,6 +29,10 @@ namespace Cryville.Common.Collections { if (_pairList != null) _pairList.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 { readonly PairCollection _self; diff --git a/Assets/Cryville/Common/Pdt/PdtInterpreter.cs b/Assets/Cryville/Common/Pdt/PdtInterpreter.cs index 54409ab..c405f33 100644 --- a/Assets/Cryville/Common/Pdt/PdtInterpreter.cs +++ b/Assets/Cryville/Common/Pdt/PdtInterpreter.cs @@ -229,7 +229,7 @@ namespace Cryville.Common.Pdt { } object InterpretObject(Type type) { var result = ReflectionHelper.InvokeEmptyConstructor(type); - bool dictflag = typeof(IDictionary).IsAssignableFrom(type); + bool pcflag = PairCollection.IsPairCollection(type); while (true) { try { ws(); } catch (IndexOutOfRangeException) { return result; } @@ -241,69 +241,47 @@ namespace Cryville.Common.Pdt { char c = GetChar(); switch (c) { case '{': - if (dictflag) { - 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(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)); - } + InterpretObjectInternal(pcflag, type, pkey, result, type => InterpretObject(type)); break; case ':': case ';': var exp = c == ';' ? _emptyexp : GetExp(); - if (dictflag) { - 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(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); - } - } + InterpretObjectInternal(pcflag, type, pkey, result, type => _binder.ChangeType(exp, type, null)); break; default: throw new InvalidOperationException("Internal error: Invalid key interpretation"); } } } + void InterpretObjectInternal(bool pcflag, Type type, object pkey, object result, Func 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(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); + } + } /// /// Interprets a key from the current position. ///