Exemple #1
0
        public CallOperator(StandaloneMetric caller, MetricExpression callee)
            : base(caller, callee)
        {
            if (caller == null || callee == null)
            {
                throw new ArgumentNullException();
            }

            _caller = caller;
            _callee = callee;
        }
        private StandaloneMetric ParseMetric()
        {
            Token token;

            // Get name
            if (!Expect(TokenType.Identifier, out token))
            {
                return(null);
            }

            var name       = token.Value;
            var parameters = new string[0];

            var nextToken = PeekNextToken();

            if (nextToken != null && nextToken.Type == TokenType.LeftBracket)
            {
                GetNextToken();

                parameters = ParseParameters();

                if (parameters == null)
                {
                    return(null);
                }

                if (!Expect(TokenType.RightBracket, out token))
                {
                    return(null);
                }
            }

            // check if name is valid metric
            if (!MetricEvaluationContext.NameToMetricMap.ContainsKey(name))
            {
                LastErrorMessage = string.Format("Undefined metric name {0}", name);
                return(null);
            }

            var metricType          = MetricEvaluationContext.NameToMetricMap[name];
            StandaloneMetric metric = null;

            try
            {
                var constructors = metricType.FindMembers(
                    MemberTypes.Constructor,
                    BindingFlags.Public | BindingFlags.Instance,
                    null,
                    null);
                foreach (var constructor in constructors)
                {
                    var parameterTypes = ((ConstructorInfo)constructor).GetParameters().Select(pi => pi.ParameterType).ToArray();
                    if (parameterTypes.Length != parameters.Length)
                    {
                        continue;
                    }

                    // try to convert parameters to the expected type
                    var objects = new object[parameterTypes.Length];

                    try
                    {
                        for (var i = 0; i < parameterTypes.Length; ++i)
                        {
                            objects[i] = Convert.ChangeType(parameters[i], parameterTypes[i]);
                        }
                    }
                    catch
                    {
                        continue;
                    }

                    // now try to create instance with converted parameters
                    metric = new StandaloneMetric((SerialMetric)Activator.CreateInstance(metricType, objects));
                    break;
                }

                if (metric == null)
                {
                    LastErrorMessage = string.Format(
                        "Can't find proper constructor for metric {0} that can be initialized by parameters {1}",
                        metricType.Name,
                        string.Join(",", parameters));

                    return(null);
                }
            }
            catch (Exception ex)
            {
                LastErrorMessage = string.Format(
                    "Create metric object {0} with parameter {1} failed. Exception {2}",
                    metricType.Name,
                    string.Join(",", parameters),
                    ex.ToString());

                return(null);
            }

            return(metric);
        }
        private MetricExpression Parse()
        {
            // parse the first part, such as MA[20]
            StandaloneMetric metric = ParseMetric();

            if (metric == null)
            {
                return(null);
            }

            // parse the call operation part, such as (MA[20])
            MetricExpression callee = null;

            Token token = PeekNextToken();

            if (token != null && token.Type == TokenType.LeftParenthese)
            {
                GetNextToken();

                callee = Parse();

                if (callee == null || !Expect(TokenType.RightParenthese, out token))
                {
                    return(null);
                }
            }

            // parse the selection part, such as .DIF
            int fieldIndex = -1;

            token = PeekNextToken();
            if (token != null && token.Type == TokenType.Dot)
            {
                GetNextToken();

                if (!Expect(TokenType.Identifier, out token))
                {
                    return(null);
                }

                string field = token.Value;

                // verify if the selection name is part of metric definition
                Type            metricType = metric.Metric.GetType();
                MetricAttribute attribute  = metricType.GetCustomAttribute <MetricAttribute>();

                if (!attribute.NameToFieldIndexMap.ContainsKey(field))
                {
                    LastErrorMessage = string.Format("{0} is not a valid subfield of metric {1}", field, metricType.Name);
                    return(null);
                }

                fieldIndex = attribute.NameToFieldIndexMap[field];
            }

            MetricExpression retValue = metric;

            if (callee != null)
            {
                retValue = new CallOperator(metric, callee);
            }

            if (fieldIndex >= 0)
            {
                retValue = new SelectionOperator(retValue, fieldIndex);
            }

            return(retValue);
        }