protected bool GetMemberNameAndAssociatedType() { memberToken = Current.Token; if (SkipStructuredDelimiters(memberToken.GetAsDelimiter())) { memberToken.Invalidate(); return(true); } memberId = null; Context.Entry e = memberToken.GetAsContextEntry(); if (e != null) { if (dictionaryAdd == null) { if (e.IsText()) { memberId = e.GetText(); } else { AddError("unable to parse member (" + e.context.name + ") as member name for " + resultType); } } else { memberId = e.Resolve(tok, scope); // "dictionary member value will be resolved later"; } if (e.tokens == Current.tokens) { Current.tokenIndex += e.tokenCount - 1; } } else { memberId = memberToken.GetAsBasicToken(); } if (memberId == null) { memberToken.index = -1; memberValue = state; return(true); } memberValue = null; return(CalculateMemberTypeBasedOnName()); }
public override string ToString() { Context.Entry pce = meta as Context.Entry; if (pce != null) { Delim d = pce.sourceMeta as Delim; if (d != null) { return(d.ToString()); } if (IsValid) { return(ToString(pce.TextRaw)); } string output = pce.context.name; if (pce.IsText()) { output += "(" + pce.GetText() + ")"; } return(output); } return(Resolve(null, null).ToString()); }
public static void op_ResolveToken(Tokenizer tok, Token token, object scope, out object value, out Type type) { value = token.Resolve(tok, scope); type = (value != null) ? value.GetType() : null; if (scope == null || type == null) { return; } // no scope, or no data, easy. we're done. string name = value as string; if (name == null) // data not a string (can't be a reference from scope), also easy. done. { List <object> args = value as List <object>; if (args != null) { for (int i = 0; i < args.Count; ++i) { bool remove = false; switch (args[i]) { case ",": remove = true; break; } if (remove) { args.RemoveAt(i--); } else { op_ResolveToken(tok, new Token(args[i], -1, -1), scope, out value, out type); args[i] = value; } } value = args; type = args.GetType(); } return; } Context.Entry e = token.GetAsContextEntry(); if (e != null && e.IsText()) { return; } // data is explicitly meant to be a string, done. switch (name) { case "null": value = null; type = null; return; case "true": value = true; type = typeof(bool); return; case "false": value = false; type = typeof(bool); return; } // otherwise, we search for the data within the given context Type scopeType = scope.GetType(); KeyValuePair <Type, Type> dType = scopeType.GetIDictionaryType(); if (dType.Key != null) { IDictionary dict = scope as IDictionary; if (dType.Key == typeof(string) && (name.StartsWith(Parser.Wildcard) || name.EndsWith(Parser.Wildcard))) { MethodInfo getKey = null; foreach (var kvp in dict) { if (getKey == null) { getKey = kvp.GetType().GetProperty("Key").GetGetMethod(); } string memberName = getKey.Invoke(kvp, null) as string; if (Parser.IsWildcardMatch(memberName, name)) { name = memberName; break; } } } if (dict.Contains(name)) { value = dict[name]; } type = (value != null) ? value.GetType() : null; return; } if (name.StartsWith(Parser.Wildcard) || name.EndsWith(Parser.Wildcard)) { FieldInfo[] fields = scopeType.GetFields(); string[] names = Array.ConvertAll(fields, f => f.Name); int index = Parser.FindIndexWithWildcard(names, name, false); if (index >= 0) { value = fields[index].GetValue(scope); type = (value != null) ? value.GetType() : null; return; } PropertyInfo[] props = scopeType.GetProperties(); names = Array.ConvertAll(props, p => p.Name); index = Parser.FindIndexWithWildcard(names, name, false); if (index >= 0) { value = props[index].GetValue(scope); type = (value != null) ? value.GetType() : null; return; } } else { FieldInfo field = scopeType.GetField(name); if (field != null) { value = field.GetValue(scope); type = (value != null) ? value.GetType() : null; return; } PropertyInfo prop = scopeType.GetProperty(name); if (prop != null) { value = prop.GetValue(scope); type = (value != null) ? value.GetType() : null; return; } } }
protected bool TryGetValue() { memberValue = null; Token token = Current.Token; object meta = token.meta; if (SkipStructuredDelimiters(meta as Delim)) { return(true); } Context.Entry context = meta as Context.Entry; if (context != null) { bool subContextUsingSameList = context.tokens == Current.tokens; if (context.IsText()) { memberValue = context.GetText(); } else { int index = Current.tokenIndex; List <Token> parseNext = subContextUsingSameList ? Current.tokens.GetRange(index, context.tokenCount) : context.tokens; if (memberType == typeof(Expression)) { memberValue = new Expression(new List <Token>() { token }); } else { if (CodeConvert.IsConvertable(memberType)) { //Show.Log(memberId + " :: " + memberValue); memberValue = context.Resolve(tok, scope); } else { //Show.Log(memberId+" : "+memberValue); if (!CodeConvert.TryParseTokens(memberType, parseNext, ref memberValue, scope, tok)) { return(false); } } } } if (subContextUsingSameList) { Current.tokenIndex += context.tokenCount - 1; // -1 because increment happens after this method } return(true); } string s = meta as string; if (s != null) { memberValue = token.ToString(s); if (!CodeConvert.TryConvert(ref memberValue, memberType)) { AddError("unable to convert (" + memberValue + ") to type '" + memberType + "'"); return(false); } return(true); } TokenSubstitution sub = meta as TokenSubstitution; if (sub != null) { memberValue = sub.value; if (!memberType.IsAssignableFrom(memberValue.GetType()) && !CodeConvert.TryConvert(ref memberValue, memberType)) { AddError("unable to convert substitution (" + memberValue + ") to type '" + memberType + "'"); return(false); } return(true); } AddError("unable to parse token with meta data " + meta); return(false); }
public static void op_ResolveToken(Tokenizer tok, Token token, object scope, out object value, out Type type) { value = token.Resolve(tok, scope); type = (value != null) ? value.GetType() : null; if (scope == null || type == null) { return; } // no scope, or no data, easy. we're done. string name = value as string; if (name == null) // data not a string (can't be a reference from scope), also easy. done. { List <object> args = value as List <object>; if (args != null) { for (int i = 0; i < args.Count; ++i) { bool remove = false; op_ResolveToken(tok, new Token(args[i], -1, -1), scope, out value, out type); switch (value as string) { case ",": remove = true; break; } if (remove) { args.RemoveAt(i--); } else { args[i] = value; } } value = args; type = args.GetType(); } return; } Context.Entry e = token.GetAsContextEntry(); if (e != null && e.IsText()) { return; } // data is explicitly meant to be a string, done. switch (name) { case "null": value = null; type = null; return; case "true": value = true; type = typeof(bool); return; case "false": value = false; type = typeof(bool); return; } // otherwise, we search for the data within the given context Type scopeType = scope.GetType(); KeyValuePair <Type, Type> dType = scopeType.GetIDictionaryType(); if (dType.Key != null) { if (dType.Key == typeof(string) && (name[0] == (Parser.Wildcard) || name[name.Length - 1] == (Parser.Wildcard))) { MethodInfo getKey = null; IEnumerator en = (IEnumerator)scopeType.GetMethod("GetEnumerator", Type.EmptyTypes).Invoke(scope, new object[] { }); //foreach(var kvp in dict) { while (en.MoveNext()) { object kvp = en.Current; if (getKey == null) { getKey = kvp.GetType().GetProperty("Key").GetGetMethod(); } string memberName = getKey.Invoke(kvp, null) as string; if (Parser.IsWildcardMatch(memberName, name)) { name = memberName; break; } } } // how to generically interface with standard Dictionary objects IDictionary dict = scope as IDictionary; if (dict != null) { if (dict.Contains(name)) { value = dict[name]; } } else { // how to generically interface with a non standard dictionary MethodInfo mi = scopeType.GetMethod("ContainsKey", new Type[] { dType.Key }); bool hasIt = (bool)mi.Invoke(scope, new object[] { name }); if (hasIt) { mi = scopeType.GetMethod("Get", new Type[] { dType.Key }); value = mi.Invoke(scope, new object[] { name }); } } type = (value != null) ? value.GetType() : null; return; } if (name[0] == (Parser.Wildcard) || name[name.Length - 1] == (Parser.Wildcard)) { FieldInfo[] fields = scopeType.GetFields(); string[] names = Array.ConvertAll(fields, f => f.Name); int index = Parser.FindIndexWithWildcard(names, name, false); if (index >= 0) { //Show.Log(name+" "+scopeType+" :"+index + " " + names.Join(", ") + " " +fields.Join(", ")); value = fields[index].GetValue(scope); type = (value != null) ? value.GetType() : null; return; } PropertyInfo[] props = scopeType.GetProperties(); names = Array.ConvertAll(props, p => p.Name); index = Parser.FindIndexWithWildcard(names, name, false); if (index >= 0) { value = props[index].GetValue(scope, null); type = (value != null) ? value.GetType() : null; return; } } else { FieldInfo field = scopeType.GetField(name); if (field != null) { value = field.GetValue(scope); type = (value != null) ? value.GetType() : null; return; } PropertyInfo prop = scopeType.GetProperty(name); if (prop != null) { value = prop.GetValue(scope, null); type = (value != null) ? value.GetType() : null; return; } } }