private object EvalContextVariable(IdentifierPart variable, TemplateContext context) { object val = null; TemplateContext lookupContext = context; while (lookupContext != null) { if (lookupContext.Variables.ContainsKey(variable.Name)) { val = lookupContext.Variables[variable.Name]; break; // found local scope var - stop looking } // look into parent scope lookupContext = lookupContext.ParentContext; } // get from context if (val == null) return null; // evaluate index expression if required val = EvalIndexer(val, variable, context); return val; }
private object EvalContextVariable(IdentifierPart variable, TemplateContext context) { object val = null; TemplateContext lookupContext = context; while (lookupContext != null) { if (lookupContext.Variables.ContainsKey(variable.Name)) { val = lookupContext.Variables[variable.Name]; break; // found local scope var - stop looking } // look into parent scope lookupContext = lookupContext.ParentContext; } // get from context if (val == null) { return(null); } // evaluate index expression if required val = EvalIndexer(val, variable, context); return(val); }
private object EvalProperty(object target, IdentifierPart property, TemplateContext context) { object val = target; // check for null if (val == null) { throw new ParserException("Cannot read property value of NULL object", Line, Column); } // get property string propName = property.Name; PropertyInfo prop = val.GetType().GetProperty(propName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (prop == null) { // build the list of available properties StringBuilder propsList = new StringBuilder(); int vi = 0; PropertyInfo[] props = val.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo p in props) { if (vi++ > 0) { propsList.Append(","); } propsList.Append(p.Name); } throw new ParserException("Public property could not be found: " + propName + "." + " Supported properties: " + propsList.ToString(), Line, Column); } // read property try { val = prop.GetValue(val, null); } catch (Exception ex) { throw new ParserException("Cannot read property value: " + ex.Message, Line, Column); } // evaluate index expression if required val = EvalIndexer(val, property, context); return(val); }
private IdentifierPart ParseIdentifierPart() { IdentifierPart part = new IdentifierPart(Current.Data, Current.Line, Current.Column); Consume(); // consume identifier // check for indexer if (Current.TokenType == TokenType.LBracket) { Consume(); // [ part.Index = ParseExpression(); Consume(TokenType.RBracket); // ] } // check for method call else if (Current.TokenType == TokenType.LParen) { Consume(); // ( part.IsMethod = true; // parse parameters while (Current.TokenType != TokenType.RParen) { part.MethodParameters.Add(ParseExpression()); if (Current.TokenType == TokenType.RParen) break; // ) Consume(TokenType.Comma); // , } Consume(TokenType.RParen); // ) } return part; }
private object EvalMethod(object target, IdentifierPart method, TemplateContext context) { object val = target; // check for null if (val == null) throw new ParserException("Cannot perform method of NULL object", Line, Column); // evaluate method parameters object[] prms = new object[method.MethodParameters.Count]; Type[] prmTypes = new Type[method.MethodParameters.Count]; for (int i = 0; i < prms.Length; i++) { prms[i] = method.MethodParameters[i].Eval(context); if (prms[i] != null) prmTypes[i] = prms[i].GetType(); else prmTypes[i] = typeof(object); // "null" parameter was specified } // find method string methodName = method.Name; MethodInfo methodInfo = val.GetType().GetMethod(methodName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public, null, prmTypes, null); if (methodInfo == null) { // failed to find exact signature // try to iterate methodInfo = val.GetType().GetMethod(methodName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); } if (methodInfo == null) { // build the list of available methods StringBuilder methodsList = new StringBuilder(); int vi = 0; MethodInfo[] methods = val.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo mi in methods) { if (vi++ > 0) methodsList.Append(","); methodsList.Append(mi.Name); } throw new ParserException("Public method could not be found: " + methodName + "." + " Available methods: " + methodsList.ToString(), Line, Column); } // call method try { val = methodInfo.Invoke(val, prms); } catch (Exception ex) { throw new ParserException("Cannot call method: " + ex.Message, Line, Column); } return val; }
private object EvalProperty(object target, IdentifierPart property, TemplateContext context) { object val = target; // check for null if (val == null) throw new ParserException("Cannot read property value of NULL object", Line, Column); // get property string propName = property.Name; PropertyInfo prop = val.GetType().GetProperty(propName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (prop == null) { // build the list of available properties StringBuilder propsList = new StringBuilder(); int vi = 0; PropertyInfo[] props = val.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo p in props) { if (vi++ > 0) propsList.Append(","); propsList.Append(p.Name); } throw new ParserException("Public property could not be found: " + propName + "." + " Supported properties: " + propsList.ToString(), Line, Column); } // read property try { val = prop.GetValue(val, null); } catch (Exception ex) { throw new ParserException("Cannot read property value: " + ex.Message, Line, Column); } // evaluate index expression if required val = EvalIndexer(val, property, context); return val; }
private object EvalIndexer(object target, IdentifierPart indexer, TemplateContext context) { if (indexer.Index == null) return target; object index = null; index = indexer.Index.Eval(context); if (index == null) throw new ParserException("Indexer expression evaluated to NULL", Line, Column); if (target == null) throw new ParserException("Cannot call indexer on NULL object", Line, Column); // get from index if required if(target is IDictionary) { // dictionary return ((IDictionary)target)[index]; } else if (target is Array) { // array if(index is Int32) return ((Array)target).GetValue((Int32)index); else throw new ParserException("Array index expression must evaluate to integer.", Line, Column); } else if (target is IList) { // list if(index is Int32) return ((IList)target)[(Int32)index]; else throw new ParserException("IList index expression must evaluate to integer.", Line, Column); } else { // call "get_Item" method MethodInfo methodInfo = target.GetType().GetMethod("get_Item", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (methodInfo != null) return methodInfo.Invoke(target, new object[] { index }); } throw new ParserException("Cannot call indexer", Line, Column); }
private object EvalMethod(object target, IdentifierPart method, TemplateContext context) { object val = target; // check for null if (val == null) { throw new ParserException("Cannot perform method of NULL object", Line, Column); } // evaluate method parameters object[] prms = new object[method.MethodParameters.Count]; Type[] prmTypes = new Type[method.MethodParameters.Count]; for (int i = 0; i < prms.Length; i++) { prms[i] = method.MethodParameters[i].Eval(context); if (prms[i] != null) { prmTypes[i] = prms[i].GetType(); } else { prmTypes[i] = typeof(object); // "null" parameter was specified } } // find method string methodName = method.Name; MethodInfo methodInfo = val.GetType().GetMethod(methodName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public, null, prmTypes, null); if (methodInfo == null) { // failed to find exact signature // try to iterate methodInfo = val.GetType().GetMethod(methodName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); } if (methodInfo == null) { // build the list of available methods StringBuilder methodsList = new StringBuilder(); int vi = 0; MethodInfo[] methods = val.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo mi in methods) { if (vi++ > 0) { methodsList.Append(","); } methodsList.Append(mi.Name); } throw new ParserException("Public method could not be found: " + methodName + "." + " Available methods: " + methodsList.ToString(), Line, Column); } // call method try { val = methodInfo.Invoke(val, prms); } catch (Exception ex) { throw new ParserException("Cannot call method: " + ex.Message, Line, Column); } return(val); }
private object EvalIndexer(object target, IdentifierPart indexer, TemplateContext context) { if (indexer.Index == null) { return(target); } object index = null; index = indexer.Index.Eval(context); if (index == null) { throw new ParserException("Indexer expression evaluated to NULL", Line, Column); } if (target == null) { throw new ParserException("Cannot call indexer on NULL object", Line, Column); } // get from index if required if (target is IDictionary) { // dictionary return(((IDictionary)target)[index]); } else if (target is Array) { // array if (index is Int32) { return(((Array)target).GetValue((Int32)index)); } else { throw new ParserException("Array index expression must evaluate to integer.", Line, Column); } } else if (target is IList) { // list if (index is Int32) { return(((IList)target)[(Int32)index]); } else { throw new ParserException("IList index expression must evaluate to integer.", Line, Column); } } else { // call "get_Item" method MethodInfo methodInfo = target.GetType().GetMethod("get_Item", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (methodInfo != null) { return(methodInfo.Invoke(target, new object[] { index })); } } throw new ParserException("Cannot call indexer", Line, Column); }