public StandaloneMetric(SerialMetric metric) { if (metric == null) { throw new ArgumentNullException("metric"); } _metric = metric; MetricAttribute attribute = _metric.GetType().GetCustomAttribute <MetricAttribute>(); _fieldNames = attribute.NameToFieldIndexMap .OrderBy(kvp => kvp.Value) .Select(kvp => kvp.Key) .ToArray(); _singleOutput = _fieldNames.Length == 1; _acceptBarInput = _metric is SingleOutputBarInputSerialMetric || _metric is MultipleOutputBarInputSerialMetric; _sobiMetric = _metric as SingleOutputBarInputSerialMetric; _soriMetric = _metric as SingleOutputRawInputSerialMetric; _mobiMetric = _metric as MultipleOutputBarInputSerialMetric; _moriMetric = _metric as MultipleOutputRawInputSerialMetric; }
static MetricEvaluationContext() { Assembly assembly = Assembly.GetExecutingAssembly(); var metrics = assembly.GetTypes() .Where(type => type.IsClass && typeof(SerialMetric).IsAssignableFrom(type)); foreach (var metric in metrics) { if (metric == typeof(SerialMetric) || metric == typeof(BarInputSerialMetric) || metric == typeof(RawInputSerialMetric) || metric == typeof(SingleOutputBarInputSerialMetric) || metric == typeof(MultipleOutputBarInputSerialMetric) || metric == typeof(SingleOutputRawInputSerialMetric) || metric == typeof(MultipleOutputRawInputSerialMetric)) { continue; } if (!typeof(SingleOutputBarInputSerialMetric).IsAssignableFrom(metric) && !typeof(SingleOutputRawInputSerialMetric).IsAssignableFrom(metric) && !typeof(MultipleOutputBarInputSerialMetric).IsAssignableFrom(metric) && !typeof(MultipleOutputRawInputSerialMetric).IsAssignableFrom(metric)) { throw new InvalidProgramException( string.Format( "Metric {0} is not inherited from class {1}, {2}, {3}, or {4}", typeof(SingleOutputBarInputSerialMetric).Name, typeof(SingleOutputRawInputSerialMetric).Name, typeof(MultipleOutputBarInputSerialMetric).Name, typeof(MultipleOutputRawInputSerialMetric).Name)); } MetricAttribute attribute = metric.GetCustomAttribute <MetricAttribute>(); if (attribute == null) { throw new InvalidProgramException( string.Format( "Metric class {0} has not been associated with MetricAttribute", metric.Name)); } // validate if metric's attribute consistent with metric class if (typeof(SingleOutputBarInputSerialMetric).IsAssignableFrom(metric) || typeof(SingleOutputRawInputSerialMetric).IsAssignableFrom(metric)) { if (attribute.NameToFieldIndexMap.Count != 1) { throw new InvalidProgramException( string.Format( "Metric class {0} should have only single output, but its attribute declared {1} outputs", metric.Name, attribute.NameToFieldIndexMap.Count)); } } else if (typeof(MultipleOutputBarInputSerialMetric).IsAssignableFrom(metric) || typeof(MultipleOutputRawInputSerialMetric).IsAssignableFrom(metric)) { if (attribute.NameToFieldIndexMap.Count <= 1) { throw new InvalidProgramException( string.Format( "Metric class {0} should have multiple output, but its attribute declared {1} output", metric.Name, attribute.NameToFieldIndexMap.Count)); } } else { // should never be here because above code has checked metric is inherited // from the expected base classes throw new InvalidProgramException("Run to unexpected code"); } // validate metric names foreach (var name in attribute.ShortNames) { if (NameToMetricAttributeMap.ContainsKey(name)) { throw new InvalidProgramException( string.Format( "Short name {0} has been defined for class {1}", name, NameToMetricMap[name].Name)); } NameToMetricAttributeMap.Add(name, attribute); NameToMetricMap.Add(name, 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); }