public ExprDotNodeFilterAnalyzerDesc GetFilterDesc(EventType[] typesPerStream,
                                                    DatetimeMethodEnum currentMethod,
                                                    ICollection <ExprNode> currentParameters,
                                                    ExprDotNodeFilterAnalyzerInput inputDesc)
 {
     return(null);
 }
        public ExprDotNodeFilterAnalyzerDesc GetFilterDesc(EventType[] typesPerStream,
                                                           DatetimeMethodEnum currentMethod,
                                                           ICollection <ExprNode> currentParameters,
                                                           ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            if (_includeLow == null || _includeHigh == null)
            {
                return(null);
            }

            int    targetStreamNum;
            String targetProperty;

            if (inputDesc is ExprDotNodeFilterAnalyzerInputStream)
            {
                var targetStream = (ExprDotNodeFilterAnalyzerInputStream)inputDesc;
                targetStreamNum = targetStream.StreamNum;
                EventType targetType = typesPerStream[targetStreamNum];
                targetProperty = targetType.StartTimestampPropertyName;
            }
            else if (inputDesc is ExprDotNodeFilterAnalyzerInputProp)
            {
                var targetStream = (ExprDotNodeFilterAnalyzerInputProp)inputDesc;
                targetStreamNum = targetStream.StreamNum;
                targetProperty  = targetStream.PropertyName;
            }
            else
            {
                return(null);
            }

            return(new ExprDotNodeFilterAnalyzerDTBetweenDesc(typesPerStream, targetStreamNum, targetProperty, _start,
                                                              _end, _includeLow.GetValueOrDefault(),
                                                              _includeHigh.GetValueOrDefault()));
        }
        public FilterExprAnalyzerAffector GetFilterDesc(
            EventType[] typesPerStream,
            DatetimeMethodEnum currentMethod,
            IList <ExprNode> currentParameters,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            if (_includeLow == null || _includeHigh == null)
            {
                return(null);
            }

            int    targetStreamNum;
            string targetProperty;

            if (inputDesc is ExprDotNodeFilterAnalyzerInputStream)
            {
                var targetStream = (ExprDotNodeFilterAnalyzerInputStream)inputDesc;
                targetStreamNum = targetStream.StreamNum;
                var targetType = typesPerStream[targetStreamNum];
                targetProperty = targetType.StartTimestampPropertyName;
            }
            else if (inputDesc is ExprDotNodeFilterAnalyzerInputProp)
            {
                var targetStream = (ExprDotNodeFilterAnalyzerInputProp)inputDesc;
                targetStreamNum = targetStream.StreamNum;
                targetProperty  = targetStream.PropertyName;
            }
            else
            {
                return(null);
            }

            return(new FilterExprAnalyzerDTBetweenAffector(
                       typesPerStream, targetStreamNum, targetProperty, _start, _end, _includeLow.Value, _includeHigh.Value));
        }
示例#4
0
 public FilterExprAnalyzerAffector GetFilterDesc(
     EventType[] typesPerStream,
     DateTimeMethodEnum currentMethod,
     IList<ExprNode> currentParameters,
     ExprDotNodeFilterAnalyzerInput inputDesc)
 {
     return null;
 }
示例#5
0
        /// <summary>
        ///     Obtain information used by filter analyzer to handle this dot-method invocation as part of query planning/indexing.
        /// </summary>
        /// <param name="typesPerStream">event types</param>
        /// <param name="currentMethod">current method</param>
        /// <param name="currentParameters">current params</param>
        /// <param name="inputDesc">descriptor of what the input to this interval method is</param>
        public FilterExprAnalyzerDTIntervalAffector GetFilterDesc(
            EventType[] typesPerStream,
            DateTimeMethodEnum currentMethod,
            IList<ExprNode> currentParameters,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            // with intervals is not currently query planned
            if (currentParameters.Count > 1) {
                return null;
            }

            // Get input (target)
            int targetStreamNum;
            string targetPropertyStart;
            string targetPropertyEnd;
            if (inputDesc is ExprDotNodeFilterAnalyzerInputStream) {
                var targetStream = (ExprDotNodeFilterAnalyzerInputStream) inputDesc;
                targetStreamNum = targetStream.StreamNum;
                var targetType = typesPerStream[targetStreamNum];
                targetPropertyStart = targetType.StartTimestampPropertyName;
                targetPropertyEnd = targetType.EndTimestampPropertyName != null
                    ? targetType.EndTimestampPropertyName
                    : targetPropertyStart;
            }
            else if (inputDesc is ExprDotNodeFilterAnalyzerInputProp) {
                var targetStream = (ExprDotNodeFilterAnalyzerInputProp) inputDesc;
                targetStreamNum = targetStream.StreamNum;
                targetPropertyStart = targetStream.PropertyName;
                targetPropertyEnd = targetStream.PropertyName;
            }
            else {
                return null;
            }

            // check parameter info
            if (parameterPropertyStart == null) {
                return null;
            }

            return new FilterExprAnalyzerDTIntervalAffector(
                currentMethod,
                typesPerStream,
                targetStreamNum,
                targetPropertyStart,
                targetPropertyEnd,
                parameterStreamNum,
                parameterPropertyStart,
                parameterPropertyEnd);
        }
示例#6
0
        public static ExprDotNodeRealizedChain GetChainEvaluators(
            int?streamOfProviderIfApplicable,
            EPType inputType,
            IList <ExprChainedSpec> chainSpec,
            ExprValidationContext validationContext,
            bool isDuckTyping,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            var            methodEvals      = new List <ExprDotEval>();
            var            currentInputType = inputType;
            EnumMethodEnum?lastLambdaFunc   = null;
            var            lastElement      = chainSpec.IsEmpty() ? null : chainSpec[chainSpec.Count - 1];
            ExprDotNodeFilterAnalyzerDesc filterAnalyzerDesc = null;

            var chainSpecStack = new ArrayDeque <ExprChainedSpec>(chainSpec);

            while (!chainSpecStack.IsEmpty())
            {
                var chainElement = chainSpecStack.RemoveFirst();
                lastLambdaFunc = null;  // reset

                // compile parameters for chain element
                var paramEvals = new ExprEvaluator[chainElement.Parameters.Count];
                var paramTypes = new Type[chainElement.Parameters.Count];
                for (var i = 0; i < chainElement.Parameters.Count; i++)
                {
                    paramEvals[i] = chainElement.Parameters[i].ExprEvaluator;
                    paramTypes[i] = paramEvals[i].ReturnType;
                }

                // check if special 'size' method
                if (currentInputType is ClassMultiValuedEPType)
                {
                    var type = (ClassMultiValuedEPType)currentInputType;
                    if ((chainElement.Name.ToLower() == "size") && paramTypes.Length == 0 && Equals(lastElement, chainElement))
                    {
                        var sizeExpr = new ExprDotEvalArraySize();
                        methodEvals.Add(sizeExpr);
                        currentInputType = sizeExpr.TypeInfo;
                        continue;
                    }
                    if ((chainElement.Name.ToLower() == "get") && paramTypes.Length == 1 && paramTypes[0].GetBoxedType() == typeof(int?))
                    {
                        var componentType = type.Component;
                        var get           = new ExprDotEvalArrayGet(paramEvals[0], componentType);
                        methodEvals.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }
                }

                // determine if there is a matching method
                var matchingMethod = false;
                var methodTarget   = GetMethodTarget(currentInputType);
                if (methodTarget != null)
                {
                    try
                    {
                        GetValidateMethodDescriptor(methodTarget, chainElement.Name, chainElement.Parameters, validationContext);
                        matchingMethod = true;
                    }
                    catch (ExprValidationException)
                    {
                        // expected
                    }
                }

                // resolve lambda
                if (chainElement.Name.IsEnumerationMethod() && (!matchingMethod || methodTarget.IsArray || methodTarget.IsImplementsInterface(typeof(ICollection <object>))))
                {
                    var enumerationMethod = EnumMethodEnumExtensions.FromName(chainElement.Name);
                    var eval = TypeHelper.Instantiate <ExprDotEvalEnumMethod>(enumerationMethod.GetImplementation());
                    eval.Init(streamOfProviderIfApplicable, enumerationMethod, chainElement.Name, currentInputType, chainElement.Parameters, validationContext);
                    currentInputType = eval.TypeInfo;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Enumeration method '" + chainElement.Name + "' has not returned type information");
                    }
                    methodEvals.Add(eval);
                    lastLambdaFunc = enumerationMethod;
                    continue;
                }

                // resolve datetime
                if (chainElement.Name.IsDateTimeMethod() && (!matchingMethod || methodTarget == typeof(DateTimeOffset?)))
                {
                    var datetimeMethod = DatetimeMethodEnumExtensions.FromName(chainElement.Name);
                    var datetimeImpl   = ExprDotEvalDTFactory.ValidateMake(
                        validationContext.StreamTypeService, chainSpecStack, datetimeMethod, chainElement.Name,
                        currentInputType, chainElement.Parameters, inputDesc,
                        validationContext.EngineImportService.TimeZone,
                        validationContext.EngineImportService.TimeAbacus);
                    currentInputType = datetimeImpl.ReturnType;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Date-time method '" + chainElement.Name + "' has not returned type information");
                    }
                    methodEvals.Add(datetimeImpl.Eval);
                    filterAnalyzerDesc = datetimeImpl.IntervalFilterDesc;
                    continue;
                }

                // try to resolve as property if the last method returned a type
                if (currentInputType is EventEPType)
                {
                    var inputEventType = ((EventEPType)currentInputType).EventType;
                    var type           = inputEventType.GetPropertyType(chainElement.Name);
                    var getter         = inputEventType.GetGetter(chainElement.Name);
                    if (type != null && getter != null)
                    {
                        var noduck = new ExprDotEvalProperty(getter, EPTypeHelper.SingleValue(type.GetBoxedType()));
                        methodEvals.Add(noduck);
                        currentInputType = EPTypeHelper.SingleValue(EPTypeHelper.GetClassSingleValued(noduck.TypeInfo));
                        continue;
                    }
                }

                // Finally try to resolve the method
                if (methodTarget != null)
                {
                    try
                    {
                        // find descriptor again, allow for duck typing
                        var desc       = GetValidateMethodDescriptor(methodTarget, chainElement.Name, chainElement.Parameters, validationContext);
                        var fastMethod = desc.FastMethod;
                        paramEvals = desc.ChildEvals;

                        ExprDotEval eval;
                        if (currentInputType is ClassEPType)
                        {
                            // if followed by an enumeration method, convert array to collection
                            if (fastMethod.ReturnType.IsArray && !chainSpecStack.IsEmpty() && chainSpecStack.First.Name.IsEnumerationMethod())
                            {
                                eval = new ExprDotMethodEvalNoDuckWrapArray(validationContext.StatementName, fastMethod, paramEvals);
                            }
                            else
                            {
                                eval = new ExprDotMethodEvalNoDuck(validationContext.StatementName, fastMethod, paramEvals);
                            }
                        }
                        else
                        {
                            eval = new ExprDotMethodEvalNoDuckUnderlying(validationContext.StatementName, fastMethod, paramEvals);
                        }
                        methodEvals.Add(eval);
                        currentInputType = eval.TypeInfo;
                    }
                    catch (Exception e)
                    {
                        if (!isDuckTyping)
                        {
                            throw new ExprValidationException(e.Message, e);
                        }
                        else
                        {
                            var duck = new ExprDotMethodEvalDuck(validationContext.StatementName, validationContext.EngineImportService, chainElement.Name, paramTypes, paramEvals);
                            methodEvals.Add(duck);
                            currentInputType = duck.TypeInfo;
                        }
                    }
                    continue;
                }

                var message = "Could not find event property, enumeration method or instance method named '" +
                              chainElement.Name + "' in " + currentInputType.ToTypeDescriptive();
                throw new ExprValidationException(message);
            }

            var intermediateEvals = methodEvals.ToArray();

            if (lastLambdaFunc != null)
            {
                ExprDotEval finalEval = null;
                if (currentInputType is EventMultiValuedEPType)
                {
                    var mvType        = (EventMultiValuedEPType)currentInputType;
                    var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(mvType.Component);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotEvalUnpackCollEventBeanTable(mvType.Component, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotEvalUnpackCollEventBean(mvType.Component);
                    }
                }
                else if (currentInputType is EventEPType)
                {
                    var epType        = (EventEPType)currentInputType;
                    var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(epType.EventType);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotEvalUnpackBeanTable(epType.EventType, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotEvalUnpackBean(epType.EventType);
                    }
                }
                if (finalEval != null)
                {
                    methodEvals.Add(finalEval);
                }
            }

            var unpackingEvals = methodEvals.ToArray();

            return(new ExprDotNodeRealizedChain(intermediateEvals, unpackingEvals, filterAnalyzerDesc));
        }
示例#7
0
        public static ExprDotEvalDTMethodDesc ValidateMake(
            StreamTypeService streamTypeService,
            Deque <ExprChainedSpec> chainSpecStack,
            DatetimeMethodEnum dtMethod,
            String dtMethodName,
            EPType inputType,
            IList <ExprNode> parameters,
            ExprDotNodeFilterAnalyzerInput inputDesc,
            TimeZoneInfo timeZone)
        {
            // verify input
            String message = "Date-time enumeration method '" + dtMethodName +
                             "' requires either a DateTime or long value as input or events of an event type that declares a timestamp property";

            if (inputType is EventEPType)
            {
                if (((EventEPType)inputType).EventType.StartTimestampPropertyName == null)
                {
                    throw new ExprValidationException(message);
                }
            }
            else
            {
                if (!(inputType is ClassEPType || inputType is NullEPType))
                {
                    throw new ExprValidationException(message + " but received " + EPTypeHelper.ToTypeDescriptive(inputType));
                }
                if (inputType is ClassEPType)
                {
                    ClassEPType classEPType = (ClassEPType)inputType;
                    if (!TypeHelper.IsDateTime(classEPType.Clazz))
                    {
                        throw new ExprValidationException(
                                  message + " but received " + classEPType.Clazz.GetTypeNameFullyQualPretty());
                    }
                }
            }

            IList <CalendarOp> calendarOps       = new List <CalendarOp>();
            ReformatOp         reformatOp        = null;
            IntervalOp         intervalOp        = null;
            DatetimeMethodEnum currentMethod     = dtMethod;
            IList <ExprNode>   currentParameters = parameters;
            String             currentMethodName = dtMethodName;

            // drain all calendar ops
            ExprDotNodeFilterAnalyzerDesc filterAnalyzerDesc = null;

            while (true)
            {
                // handle the first one only if its a calendar op
                var evaluators = GetEvaluators(currentParameters);
                var opFactory  = currentMethod.MetaData().OpFactory;

                // compile parameter abstract for validation against available footprints
                var footprintProvided = DotMethodUtil.GetProvidedFootprint(currentParameters);

                // validate parameters
                DotMethodUtil.ValidateParametersDetermineFootprint(
                    currentMethod.Footprints(),
                    DotMethodTypeEnum.DATETIME,
                    currentMethodName, footprintProvided,
                    DotMethodInputTypeMatcherImpl.DEFAULT_ALL);

                if (opFactory is CalendarOpFactory)
                {
                    CalendarOp calendarOp = ((CalendarOpFactory)opFactory).GetOp(currentMethod, currentMethodName, currentParameters, evaluators);
                    calendarOps.Add(calendarOp);
                }
                else if (opFactory is ReformatOpFactory)
                {
                    reformatOp = ((ReformatOpFactory)opFactory).GetOp(timeZone, currentMethod, currentMethodName, currentParameters);

                    // compile filter analyzer information if there are no calendar ops in the chain
                    if (calendarOps.IsEmpty())
                    {
                        filterAnalyzerDesc = reformatOp.GetFilterDesc(streamTypeService.EventTypes, currentMethod, currentParameters, inputDesc);
                    }
                    else
                    {
                        filterAnalyzerDesc = null;
                    }
                }
                else if (opFactory is IntervalOpFactory)
                {
                    intervalOp = ((IntervalOpFactory)opFactory).GetOp(streamTypeService, currentMethod, currentMethodName, currentParameters, evaluators);

                    // compile filter analyzer information if there are no calendar ops in the chain
                    if (calendarOps.IsEmpty())
                    {
                        filterAnalyzerDesc = intervalOp.GetFilterDesc(streamTypeService.EventTypes, currentMethod, currentParameters, inputDesc);
                    }
                    else
                    {
                        filterAnalyzerDesc = null;
                    }
                }
                else
                {
                    throw new IllegalStateException("Invalid op factory class " + opFactory);
                }

                // see if there is more
                if (chainSpecStack.IsEmpty() || !DatetimeMethodEnumExtensions.IsDateTimeMethod(chainSpecStack.First.Name))
                {
                    break;
                }

                // pull next
                var next = chainSpecStack.RemoveFirst();
                currentMethod     = DatetimeMethodEnumExtensions.FromName(next.Name);
                currentParameters = next.Parameters;
                currentMethodName = next.Name;

                if ((reformatOp != null || intervalOp != null))
                {
                    throw new ExprValidationException("Invalid input for date-time method '" + next.Name + "'");
                }
            }

            ExprDotEval dotEval;
            EPType      returnType;

            dotEval    = new ExprDotEvalDT(calendarOps, timeZone, reformatOp, intervalOp, EPTypeHelper.GetClassSingleValued(inputType), EPTypeHelper.GetEventTypeSingleValued(inputType));
            returnType = dotEval.TypeInfo;
            return(new ExprDotEvalDTMethodDesc(dotEval, returnType, filterAnalyzerDesc));
        }
示例#8
0
        public static ExprDotDTMethodDesc ValidateMake(
            StreamTypeService streamTypeService,
            Deque<Chainable> chainSpecStack,
            DatetimeMethodDesc dtMethod,
            string dtMethodName,
            EPType inputType,
            IList<ExprNode> parameters,
            ExprDotNodeFilterAnalyzerInput inputDesc,
            TimeAbacus timeAbacus,
            TableCompileTimeResolver tableCompileTimeResolver,
            ImportServiceCompileTime importService,
            StatementRawInfo statementRawInfo)
        {
            // verify input
            var message = "Date-time enumeration method '" +
                          dtMethodName +
                          "' requires either a DateTimeEx, DateTimeOffset, DateTime, or long value as input or events of an event type that declares a timestamp property";
            if (inputType is EventEPType eventEpType) {
                if (eventEpType.EventType.StartTimestampPropertyName == null) {
                    throw new ExprValidationException(message);
                }
            }
            else {
                if (!(inputType is ClassEPType || inputType is NullEPType)) {
                    throw new ExprValidationException(
                        message + " but received " + inputType.ToTypeDescriptive());
                }

                if (inputType is ClassEPType classEpType) {
                    if (!TypeHelper.IsDateTime(classEpType.Clazz)) {
                        throw new ExprValidationException(
                            message + " but received " + classEpType.Clazz.CleanName());
                    }
                }
            }

            IList<CalendarForge> calendarForges = new List<CalendarForge>();
            ReformatForge reformatForge = null;
            IntervalForge intervalForge = null;
            var currentMethod = dtMethod;
            var currentParameters = parameters;
            var currentMethodName = dtMethodName;

            // drain all calendar op
            FilterExprAnalyzerAffector filterAnalyzerDesc = null;
            while (true) {
                // handle the first one only if its a calendar op
                var forges = GetForges(currentParameters);
                var opFactory = currentMethod.ForgeFactory;

                // compile parameter abstract for validation against available footprints
                var footprintProvided = DotMethodUtil.GetProvidedFootprint(currentParameters);

                // validate parameters
                var footprintFound = DotMethodUtil.ValidateParametersDetermineFootprint(
                    currentMethod.Footprints,
                    DotMethodTypeEnum.DATETIME,
                    currentMethodName,
                    footprintProvided,
                    DotMethodInputTypeMatcherImpl.DEFAULT_ALL);

                if (opFactory is CalendarForgeFactory calendarForgeFactory) {
                    var calendarForge = calendarForgeFactory.GetOp(
                        currentMethod,
                        currentMethodName,
                        currentParameters,
                        forges);
                    calendarForges.Add(calendarForge);
                }
                else if (opFactory is ReformatForgeFactory reformatForgeFactory) {
                    reformatForge = reformatForgeFactory.GetForge(
                        inputType,
                        timeAbacus,
                        currentMethod,
                        currentMethodName,
                        currentParameters);

                    // compile filter analyzer information if there are no calendar op in the chain
                    if (calendarForges.IsEmpty()) {
                        filterAnalyzerDesc = reformatForge.GetFilterDesc(
                            streamTypeService.EventTypes,
                            currentMethod,
                            currentParameters,
                            inputDesc);
                    }
                    else {
                        filterAnalyzerDesc = null;
                    }
                }
                else if (opFactory is IntervalForgeFactory intervalForgeFactory) {
                    intervalForge = intervalForgeFactory.GetForge(
                        streamTypeService,
                        currentMethod,
                        currentMethodName,
                        currentParameters,
                        timeAbacus,
                        tableCompileTimeResolver);

                    // compile filter analyzer information if there are no calendar op in the chain
                    if (calendarForges.IsEmpty()) {
                        filterAnalyzerDesc = intervalForge.GetFilterDesc(
                            streamTypeService.EventTypes,
                            currentMethod,
                            currentParameters,
                            inputDesc);
                    }
                }
                else if (opFactory is DTMPluginForgeFactory dtmPluginForgeFactory) {
                    var usageDesc = new DateTimeMethodValidateContext(
                        footprintFound,
                        streamTypeService,
                        currentMethod,
                        currentParameters,
                        statementRawInfo);
                    var ops = dtmPluginForgeFactory.Validate(usageDesc);
                    if (ops == null) {
                        throw new ExprValidationException(
                            "Plug-in datetime method provider " + dtmPluginForgeFactory.GetType() + " returned a null-value for the operations");
                    }

                    var input = EPTypeHelper.GetClassSingleValued(inputType);
                    if (ops is DateTimeMethodOpsModify dateTimeMethodOpsModify) {
                        calendarForges.Add(new DTMPluginValueChangeForge(input, dateTimeMethodOpsModify, usageDesc.CurrentParameters));
                    }
                    else if (ops is DateTimeMethodOpsReformat dateTimeMethodOpsReformat) {
                        reformatForge = new DTMPluginReformatForge(input, dateTimeMethodOpsReformat, usageDesc.CurrentParameters);
                    }
                    else {
                        throw new ExprValidationException("Plug-in datetime method ops " + ops.GetType() + " is not recognized");
                    }

                    // no action
                }
                else {
                    throw new IllegalStateException("Invalid op factory class " + opFactory);
                }

                // see if there is more
                if (chainSpecStack.IsEmpty() || !DatetimeMethodResolver.IsDateTimeMethod(chainSpecStack.First.GetRootNameOrEmptyString(), importService)) {
                    break;
                }

                // pull next
                var next = chainSpecStack.RemoveFirst();
                currentMethodName = next.GetRootNameOrEmptyString();
                currentMethod = DatetimeMethodResolver.FromName(currentMethodName, importService);
                currentParameters = next.GetParametersOrEmpty();

                if (reformatForge != null || intervalForge != null) {
                    throw new ExprValidationException("Invalid input for date-time method '" + currentMethodName + "'");
                }
            }

            var dotForge = new ExprDotDTForge(
                calendarForges,
                timeAbacus,
                reformatForge,
                intervalForge,
                inputType.GetClassSingleValued(),
                inputType.GetEventTypeSingleValued());
            var returnType = dotForge.TypeInfo;
            return new ExprDotDTMethodDesc(dotForge, returnType, filterAnalyzerDesc);
        }
示例#9
0
        public static ExprDotNodeRealizedChain GetChainEvaluators(
            int? streamOfProviderIfApplicable,
            EPType inputType,
            IList<ExprChainedSpec> chainSpec,
            ExprValidationContext validationContext,
            bool isDuckTyping,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            IList<ExprDotForge> methodForges = new List<ExprDotForge>();
            var currentInputType = inputType;
            EnumMethodEnum? lastLambdaFunc = null;
            var lastElement = chainSpec.IsEmpty() ? null : chainSpec[chainSpec.Count - 1];
            FilterExprAnalyzerAffector filterAnalyzerDesc = null;

            Deque<ExprChainedSpec> chainSpecStack = new ArrayDeque<ExprChainedSpec>(chainSpec);
            while (!chainSpecStack.IsEmpty()) {
                var chainElement = chainSpecStack.RemoveFirst();
                lastLambdaFunc = null; // reset

                // compile parameters for chain element
                var paramForges = new ExprForge[chainElement.Parameters.Count];
                var paramTypes = new Type[chainElement.Parameters.Count];
                for (var i = 0; i < chainElement.Parameters.Count; i++) {
                    paramForges[i] = chainElement.Parameters[i].Forge;
                    paramTypes[i] = paramForges[i].EvaluationType;
                }

                // check if special 'size' method
                if (currentInputType is ClassMultiValuedEPType) {
                    var type = (ClassMultiValuedEPType) currentInputType;
                    if (chainElement.Name.Equals("size", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 0 &&
                        lastElement == chainElement) {
                        var sizeExpr = new ExprDotForgeArraySize();
                        methodForges.Add(sizeExpr);
                        currentInputType = sizeExpr.TypeInfo;
                        continue;
                    }

                    if (chainElement.Name.Equals("get", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 1 &&
                        Boxing.GetBoxedType(paramTypes[0]) == typeof(int?)) {
                        var componentType = Boxing.GetBoxedType(type.Component);
                        var get = new ExprDotForgeArrayGet(paramForges[0], componentType);
                        methodForges.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }
                }

                // determine if there is a matching method
                var matchingMethod = false;
                var methodTarget = GetMethodTarget(currentInputType);
                if (methodTarget != null) {
                    try {
                        GetValidateMethodDescriptor(
                            methodTarget,
                            chainElement.Name,
                            chainElement.Parameters,
                            validationContext);
                        matchingMethod = true;
                    }
                    catch (ExprValidationException) {
                        // expected
                    }
                }

                if (EnumMethodEnumExtensions.IsEnumerationMethod(chainElement.Name) &&
                    (!matchingMethod || methodTarget.IsArray || methodTarget.IsGenericCollection())) {
                    var enumerationMethod = EnumMethodEnumExtensions.FromName(chainElement.Name);
                    if (enumerationMethod == null) {
                        throw new EPException("unable to determine enumeration method from name");
                    }

                    var eval = TypeHelper.Instantiate<ExprDotForgeEnumMethod>(
                        enumerationMethod.Value.GetImplementation());
                    eval.Init(
                        streamOfProviderIfApplicable,
                        enumerationMethod.Value,
                        chainElement.Name,
                        currentInputType,
                        chainElement.Parameters,
                        validationContext);
                    currentInputType = eval.TypeInfo;
                    if (currentInputType == null) {
                        throw new IllegalStateException(
                            "Enumeration method '" + chainElement.Name + "' has not returned type information");
                    }

                    methodForges.Add(eval);
                    lastLambdaFunc = enumerationMethod;
                    continue;
                }

                // resolve datetime
                if (DatetimeMethodEnumHelper.IsDateTimeMethod(chainElement.Name) &&
                    (!matchingMethod ||
                     methodTarget == typeof(DateTimeEx) ||
                     methodTarget == typeof(DateTimeOffset) ||
                     methodTarget == typeof(DateTime))) {
                    var dateTimeMethod = DatetimeMethodEnumHelper.FromName(chainElement.Name);
                    var datetimeImpl = ExprDotDTFactory.ValidateMake(
                        validationContext.StreamTypeService,
                        chainSpecStack,
                        dateTimeMethod,
                        chainElement.Name,
                        currentInputType,
                        chainElement.Parameters,
                        inputDesc,
                        validationContext.ImportService.TimeAbacus,
                        null,
                        validationContext.TableCompileTimeResolver);
                    currentInputType = datetimeImpl.ReturnType;
                    if (currentInputType == null) {
                        throw new IllegalStateException(
                            "Date-time method '" + chainElement.Name + "' has not returned type information");
                    }

                    methodForges.Add(datetimeImpl.Forge);
                    filterAnalyzerDesc = datetimeImpl.IntervalFilterDesc;
                    continue;
                }

                // try to resolve as property if the last method returned a type
                if (currentInputType is EventEPType) {
                    var inputEventType = (EventTypeSPI) ((EventEPType) currentInputType).EventType;
                    var type = inputEventType.GetPropertyType(chainElement.Name);
                    var getter = inputEventType.GetGetterSPI(chainElement.Name);
                    if (type != null && getter != null) {
                        var noduck = new ExprDotForgeProperty(
                            getter,
                            EPTypeHelper.SingleValue(Boxing.GetBoxedType(type)));
                        methodForges.Add(noduck);
                        currentInputType = EPTypeHelper.SingleValue(EPTypeHelper.GetClassSingleValued(noduck.TypeInfo));
                        continue;
                    }
                }

                // Finally try to resolve the method
                if (methodTarget != null) {
                    try {
                        // find descriptor again, allow for duck typing
                        var desc = GetValidateMethodDescriptor(
                            methodTarget,
                            chainElement.Name,
                            chainElement.Parameters,
                            validationContext);
                        paramForges = desc.ChildForges;
                        ExprDotForge forge;
                        if (currentInputType is ClassEPType) {
                            // if followed by an enumeration method, convert array to collection
                            if (desc.ReflectionMethod.ReturnType.IsArray &&
                                !chainSpecStack.IsEmpty() &&
                                EnumMethodEnumExtensions.IsEnumerationMethod(chainSpecStack.First.Name)) {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.WRAPARRAY);
                            }
                            else {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.PLAIN);
                            }
                        }
                        else {
                            forge = new ExprDotMethodForgeNoDuck(
                                validationContext.StatementName,
                                desc.ReflectionMethod,
                                paramForges,
                                ExprDotMethodForgeNoDuck.DuckType.UNDERLYING);
                        }

                        methodForges.Add(forge);
                        currentInputType = forge.TypeInfo;
                    }
                    catch (Exception e) {
                        if (!isDuckTyping) {
                            throw new ExprValidationException(e.Message, e);
                        }

                        var duck = new ExprDotMethodForgeDuck(
                            validationContext.StatementName,
                            validationContext.ImportService,
                            chainElement.Name,
                            paramTypes,
                            paramForges);
                        methodForges.Add(duck);
                        currentInputType = duck.TypeInfo;
                    }

                    continue;
                }

                var message = "Could not find event property, enumeration method or instance method named '" +
                                 chainElement.Name +
                                 "' in " +
                                 EPTypeHelper.ToTypeDescriptive(currentInputType);
                throw new ExprValidationException(message);
            }

            var intermediateEvals = methodForges.ToArray();

            if (lastLambdaFunc != null) {
                ExprDotForge finalEval = null;
                if (currentInputType is EventMultiValuedEPType) {
                    var mvType = (EventMultiValuedEPType) currentInputType;
                    var tableMetadata =
                        validationContext.TableCompileTimeResolver.ResolveTableFromEventType(mvType.Component);
                    if (tableMetadata != null) {
                        finalEval = new ExprDotForgeUnpackCollEventBeanTable(mvType.Component, tableMetadata);
                    }
                    else {
                        finalEval = new ExprDotForgeUnpackCollEventBean(mvType.Component);
                    }
                }
                else if (currentInputType is EventEPType) {
                    var epType = (EventEPType) currentInputType;
                    var tableMetadata =
                        validationContext.TableCompileTimeResolver.ResolveTableFromEventType(epType.EventType);
                    if (tableMetadata != null) {
                        finalEval = new ExprDotForgeUnpackBeanTable(epType.EventType, tableMetadata);
                    }
                    else {
                        finalEval = new ExprDotForgeUnpackBean(epType.EventType);
                    }
                }

                if (finalEval != null) {
                    methodForges.Add(finalEval);
                }
            }

            var unpackingForges = methodForges.ToArray();
            return new ExprDotNodeRealizedChain(intermediateEvals, unpackingForges, filterAnalyzerDesc);
        }
示例#10
0
        public static ExprDotNodeRealizedChain GetChainEvaluators(
            int?streamOfProviderIfApplicable,
            EPType inputType,
            IList <Chainable> chainSpec,
            ExprValidationContext validationContext,
            bool isDuckTyping,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            var                        methodForges       = new List <ExprDotForge>();
            var                        currentInputType   = inputType;
            EnumMethodDesc             lastLambdaFunc     = null;
            var                        lastElement        = chainSpec.IsEmpty() ? null : chainSpec[chainSpec.Count - 1];
            FilterExprAnalyzerAffector filterAnalyzerDesc = null;

            Deque <Chainable> chainSpecStack = new ArrayDeque <Chainable>(chainSpec);

            while (!chainSpecStack.IsEmpty())
            {
                var chainElement     = chainSpecStack.RemoveFirst();
                var parameters       = chainElement.GetParametersOrEmpty();
                var chainElementName = chainElement.GetRootNameOrEmptyString();
                var last             = chainSpecStack.IsEmpty();
                lastLambdaFunc = null;                 // reset

                // compile parameters for chain element
                var paramForges = new ExprForge[parameters.Count];
                var paramTypes  = new Type[parameters.Count];
                for (var i = 0; i < parameters.Count; i++)
                {
                    paramForges[i] = parameters[i].Forge;
                    paramTypes[i]  = paramForges[i].EvaluationType;
                }

                // check if special 'size' method
                if (currentInputType is ClassMultiValuedEPType)
                {
                    var type = (ClassMultiValuedEPType)currentInputType;
                    if (string.Equals(chainElementName, "size", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 0 &&
                        lastElement == chainElement)
                    {
                        ExprDotForge size;
                        var          containerType = ((ClassMultiValuedEPType)currentInputType).Container;
                        if (containerType.IsArray)
                        {
                            size = new ExprDotForgeSizeArray();
                        }
                        else
                        {
                            size = new ExprDotForgeSizeCollection();
                        }

                        methodForges.Add(size);
                        currentInputType = size.TypeInfo;
                        continue;
                    }

                    if (string.Equals(chainElementName, "get", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 1 &&
                        paramTypes[0].GetBoxedType() == typeof(int?))
                    {
                        ExprDotForge get;
                        var          componentType = type.Component.GetBoxedType();
                        if (type.Container.IsArray)
                        {
                            get = new ExprDotForgeGetArray(paramForges[0], componentType);
                        }
                        else
                        {
                            get = new ExprDotForgeGetCollection(paramForges[0], componentType);
                        }

                        methodForges.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }

                    if (chainElement is ChainableArray && type.Container.IsArray)
                    {
                        var array     = (ChainableArray)chainElement;
                        var typeInfo  = currentInputType;
                        var indexExpr = ChainableArray.ValidateSingleIndexExpr(
                            array.Indexes,
                            () => "operation on type " + typeInfo.ToTypeDescriptive());
                        var componentType = type.Component.GetBoxedType();
                        var get           = new ExprDotForgeGetArray(indexExpr.Forge, componentType);
                        methodForges.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }
                }

                // determine if there is a matching method or property
                var methodTarget   = GetMethodTarget(currentInputType);
                var matchingMethod = false;
                if (methodTarget != null && (!(chainElement is ChainableArray)))
                {
                    try {
                        GetValidateMethodDescriptor(methodTarget, chainElementName, parameters, validationContext);
                        matchingMethod = true;
                    }
                    catch (ExprValidationException) {
                        // expected
                    }
                }

                if (EnumMethodResolver.IsEnumerationMethod(chainElementName, validationContext.ImportService) &&
                    (!matchingMethod || methodTarget.IsArray || methodTarget.IsGenericCollection()))
                {
                    var enumerationMethod = EnumMethodResolver.FromName(chainElementName, validationContext.ImportService);
                    if (enumerationMethod == null)
                    {
                        throw new EPException("unable to determine enumeration method from name");
                    }

                    var eval = enumerationMethod.Factory.Invoke(chainElement.GetParametersOrEmpty().Count);
                    if (currentInputType is ClassEPType classEpType && classEpType.Clazz.IsGenericCollection() && !classEpType.Clazz.IsArray)
                    {
                        currentInputType = EPTypeHelper.CollectionOfSingleValue(typeof(object), null);
                    }

                    eval.Init(streamOfProviderIfApplicable, enumerationMethod, chainElementName, currentInputType, parameters, validationContext);
                    currentInputType = eval.TypeInfo;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Enumeration method '" + chainElementName + "' has not returned type information");
                    }

                    methodForges.Add(eval);
                    lastLambdaFunc = enumerationMethod;
                    continue;
                }

                // resolve datetime
                if (DatetimeMethodResolver.IsDateTimeMethod(chainElementName, validationContext.ImportService) &&
                    (!matchingMethod ||
                     methodTarget == typeof(DateTimeEx) ||
                     methodTarget == typeof(DateTimeOffset) ||
                     methodTarget == typeof(DateTime)))
                {
                    var datetimeMethod = DatetimeMethodResolver.FromName(chainElementName, validationContext.ImportService);
                    var datetimeImpl   = ExprDotDTFactory.ValidateMake(
                        validationContext.StreamTypeService,
                        chainSpecStack,
                        datetimeMethod,
                        chainElementName,
                        currentInputType,
                        parameters,
                        inputDesc,
                        validationContext.ImportService.TimeAbacus,
                        validationContext.TableCompileTimeResolver,
                        validationContext.ImportService,
                        validationContext.StatementRawInfo);
                    currentInputType = datetimeImpl.ReturnType;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException(
                                  "Date-time method '" + chainElementName + "' has not returned type information");
                    }

                    methodForges.Add(datetimeImpl.Forge);
                    filterAnalyzerDesc = datetimeImpl.IntervalFilterDesc;
                    continue;
                }

                // try to resolve as property if the last method returned a type
                if (currentInputType is EventEPType)
                {
                    if (chainElement is ChainableArray)
                    {
                        throw new ExprValidationException("Could not perform array operation on type " + currentInputType.ToTypeDescriptive());
                    }

                    var          inputEventType = (EventTypeSPI)((EventEPType)currentInputType).EventType;
                    var          type           = inputEventType.GetPropertyType(chainElementName);
                    var          getter         = inputEventType.GetGetterSPI(chainElementName);
                    var          fragmentType   = inputEventType.GetFragmentType(chainElementName);
                    ExprDotForge forge;
                    if (type != null && getter != null)
                    {
                        if (fragmentType == null || last)
                        {
                            forge            = new ExprDotForgeProperty(getter, EPTypeHelper.SingleValue(type.GetBoxedType()));
                            currentInputType = forge.TypeInfo;
                        }
                        else
                        {
                            if (!fragmentType.IsIndexed)
                            {
                                currentInputType = EPTypeHelper.SingleEvent(fragmentType.FragmentType);
                            }
                            else
                            {
                                currentInputType = EPTypeHelper.ArrayOfEvents(fragmentType.FragmentType);
                            }

                            forge = new ExprDotForgePropertyFragment(getter, currentInputType);
                        }

                        methodForges.Add(forge);
                        continue;
                    }
                }

                if (currentInputType is EventMultiValuedEPType eventMultiValuedEpType && chainElement is ChainableArray chainableArray)
                {
                    var inputEventType = (EventTypeSPI)eventMultiValuedEpType.Component;
                    var typeInfo       = currentInputType;
                    var indexExpr      = ChainableArray.ValidateSingleIndexExpr(
                        chainableArray.Indexes,
                        () => "operation on type " + typeInfo.ToTypeDescriptive());
                    currentInputType = EPTypeHelper.SingleEvent(inputEventType);
                    var forge = new ExprDotForgeEventArrayAtIndex(currentInputType, indexExpr);
                    methodForges.Add(forge);
                    continue;
                }

                // Finally try to resolve the method
                if (methodTarget != null && !(chainElement is ChainableArray))
                {
                    try {
                        // find descriptor again, allow for duck typing
                        var desc = GetValidateMethodDescriptor(methodTarget, chainElementName, parameters, validationContext);
                        paramForges = desc.ChildForges;
                        ExprDotForge forge;
                        if (currentInputType is ClassEPType)
                        {
                            // if followed by an enumeration method, convert array to collection
                            if (desc.ReflectionMethod.ReturnType.IsArray &&
                                !chainSpecStack.IsEmpty() &&
                                EnumMethodResolver.IsEnumerationMethod(chainSpecStack.First.GetRootNameOrEmptyString(), validationContext.ImportService))
                            {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.WRAPARRAY);
                            }
                            else
                            {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.PLAIN);
                            }
                        }
                        else
                        {
                            forge = new ExprDotMethodForgeNoDuck(
                                validationContext.StatementName,
                                desc.ReflectionMethod,
                                paramForges,
                                ExprDotMethodForgeNoDuck.DuckType.UNDERLYING);
                        }

                        methodForges.Add(forge);
                        currentInputType = forge.TypeInfo;
                    }
                    catch (Exception e) {
                        if (!isDuckTyping)
                        {
                            throw new ExprValidationException(e.Message, e);
                        }

                        var duck = new ExprDotMethodForgeDuck(
                            validationContext.StatementName,
                            validationContext.ImportService,
                            chainElementName,
                            paramTypes,
                            paramForges);
                        methodForges.Add(duck);
                        currentInputType = duck.TypeInfo;
                    }

                    continue;
                }

                string message;
                if (!(chainElement is ChainableArray))
                {
                    message = "Could not find event property or method named '" + chainElementName + "' in " + currentInputType.ToTypeDescriptive();
                }
                else
                {
                    message = "Could not perform array operation on type " + currentInputType.ToTypeDescriptive();
                }

                throw new ExprValidationException(message);
            }

            var intermediateEvals = methodForges.ToArray();

            if (lastLambdaFunc != null)
            {
                ExprDotForge finalEval = null;
                if (currentInputType is EventMultiValuedEPType mvType)
                {
                    var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(mvType.Component);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotForgeUnpackCollEventBeanTable(mvType.Component, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotForgeUnpackCollEventBean(mvType.Component);
                    }
                }
                else if (currentInputType is EventEPType epType)
                {
                    var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(epType.EventType);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotForgeUnpackBeanTable(epType.EventType, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotForgeUnpackBean(epType.EventType);
                    }
                }

                if (finalEval != null)
                {
                    methodForges.Add(finalEval);
                }
            }

            var unpackingForges = methodForges.ToArray();

            return(new ExprDotNodeRealizedChain(intermediateEvals, unpackingForges, filterAnalyzerDesc));
        }
示例#11
0
        public static ExprDotDTMethodDesc ValidateMake(
            StreamTypeService streamTypeService,
            Deque<ExprChainedSpec> chainSpecStack,
            DateTimeMethodEnum dtMethod,
            string dtMethodName,
            EPType inputType,
            IList<ExprNode> parameters,
            ExprDotNodeFilterAnalyzerInput inputDesc,
            TimeAbacus timeAbacus,
            ExprEvaluatorContext exprEvaluatorContext,
            TableCompileTimeResolver tableCompileTimeResolver)
        {
            // verify input
            var message = "Date-time enumeration method '" +
                          dtMethodName +
                          "' requires either a DateTimeEx, DateTimeOffset, DateTime, or long value as input or events of an event type that declares a timestamp property";
            if (inputType is EventEPType) {
                if (((EventEPType) inputType).EventType.StartTimestampPropertyName == null) {
                    throw new ExprValidationException(message);
                }
            }
            else {
                if (!(inputType is ClassEPType || inputType is NullEPType)) {
                    throw new ExprValidationException(
                        message + " but received " + inputType.ToTypeDescriptive());
                }

                if (inputType is ClassEPType) {
                    var classEPType = (ClassEPType) inputType;
                    if (!TypeHelper.IsDateTime(classEPType.Clazz)) {
                        throw new ExprValidationException(
                            message + " but received " + classEPType.Clazz.CleanName());
                    }
                }
            }

            IList<CalendarForge> calendarForges = new List<CalendarForge>();
            ReformatForge reformatForge = null;
            IntervalForge intervalForge = null;
            var currentMethod = dtMethod;
            var currentParameters = parameters;
            var currentMethodName = dtMethodName;

            // drain all calendar op
            FilterExprAnalyzerAffector filterAnalyzerDesc = null;
            while (true) {
                // handle the first one only if its a calendar op
                var forges = GetForges(currentParameters);
                var opFactory = currentMethod.GetForgeFactory();

                // compile parameter abstract for validation against available footprints
                DotMethodFPProvided footprintProvided = DotMethodUtil.GetProvidedFootprint(currentParameters);

                // validate parameters
                DotMethodUtil.ValidateParametersDetermineFootprint(
                    currentMethod.GetFootprints(),
                    DotMethodTypeEnum.DATETIME,
                    currentMethodName,
                    footprintProvided,
                    DotMethodInputTypeMatcherImpl.DEFAULT_ALL);

                if (opFactory is CalendarForgeFactory) {
                    var calendarForge = ((CalendarForgeFactory) currentMethod.GetForgeFactory()).GetOp(
                        currentMethod,
                        currentMethodName,
                        currentParameters,
                        forges);
                    calendarForges.Add(calendarForge);
                }
                else if (opFactory is ReformatForgeFactory) {
                    reformatForge = ((ReformatForgeFactory) opFactory).GetForge(
                        inputType,
                        timeAbacus,
                        currentMethod,
                        currentMethodName,
                        currentParameters,
                        exprEvaluatorContext);

                    // compile filter analyzer information if there are no calendar op in the chain
                    if (calendarForges.IsEmpty()) {
                        filterAnalyzerDesc = reformatForge.GetFilterDesc(
                            streamTypeService.EventTypes,
                            currentMethod,
                            currentParameters,
                            inputDesc);
                    }
                    else {
                        filterAnalyzerDesc = null;
                    }
                }
                else if (opFactory is IntervalForgeFactory) {
                    intervalForge = ((IntervalForgeFactory) opFactory).GetForge(
                        streamTypeService,
                        currentMethod,
                        currentMethodName,
                        currentParameters,
                        timeAbacus,
                        tableCompileTimeResolver);

                    // compile filter analyzer information if there are no calendar op in the chain
                    if (calendarForges.IsEmpty()) {
                        filterAnalyzerDesc = intervalForge.GetFilterDesc(
                            streamTypeService.EventTypes,
                            currentMethod,
                            currentParameters,
                            inputDesc);
                    }
                    else {
                        filterAnalyzerDesc = null;
                    }
                }
                else {
                    throw new IllegalStateException("Invalid op factory class " + opFactory);
                }

                // see if there is more
                if (chainSpecStack.IsEmpty() || !DatetimeMethodEnumHelper.IsDateTimeMethod(chainSpecStack.First.Name)) {
                    break;
                }

                // pull next
                var next = chainSpecStack.RemoveFirst();
                currentMethod = DatetimeMethodEnumHelper.FromName(next.Name);
                currentParameters = next.Parameters;
                currentMethodName = next.Name;

                if (reformatForge != null || intervalForge != null) {
                    throw new ExprValidationException("Invalid input for date-time method '" + next.Name + "'");
                }
            }

            ExprDotForge dotForge;
            EPType returnType;

            dotForge = new ExprDotDTForge(
                calendarForges,
                timeAbacus,
                reformatForge,
                intervalForge,
                inputType.GetClassSingleValued(),
                inputType.GetEventTypeSingleValued());
            returnType = dotForge.TypeInfo;
            return new ExprDotDTMethodDesc(dotForge, returnType, filterAnalyzerDesc);
        }