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;
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }