public static CodegenExpression Codegen( IntervalOpDateTimeOffsetForge forge, CodegenExpression start, CodegenExpression end, CodegenExpression parameter, Type parameterType, CodegenMethodScope codegenMethodScope, ExprForgeCodegenSymbol exprSymbol, CodegenClassScope codegenClassScope) { var methodNode = codegenMethodScope .MakeChild(typeof(bool?), typeof(IntervalOpDateTimeOffsetEval), codegenClassScope) .AddParam(typeof(long), "startTs") .AddParam(typeof(long), "endTs") .AddParam(typeof(DateTimeOffset), "parameter"); methodNode.Block .DeclareVar<long>( "time", StaticMethod( typeof(DatetimeLongCoercerDateTimeOffset), "CoerceToMillis", Ref("parameter"))) .MethodReturn( forge.intervalComputer.Codegen( Ref("startTs"), Ref("endTs"), Ref("time"), Ref("time"), methodNode, exprSymbol, codegenClassScope)); return LocalMethod(methodNode, start, end, parameter); }
public IntervalForgeImpl( DateTimeMethodEnum method, string methodNameUse, StreamTypeService streamTypeService, IList<ExprNode> expressions, TimeAbacus timeAbacus, TableCompileTimeResolver tableCompileTimeResolver) { ExprForge forgeEndTimestamp = null; Type timestampType; if (expressions[0] is ExprStreamUnderlyingNode) { var und = (ExprStreamUnderlyingNode) expressions[0]; parameterStreamNum = und.StreamId; var type = streamTypeService.EventTypes[parameterStreamNum]; parameterPropertyStart = type.StartTimestampPropertyName; if (parameterPropertyStart == null) { throw new ExprValidationException( "For date-time method '" + methodNameUse + "' the first parameter is event type '" + type.Name + "', however no timestamp property has been defined for this event type"); } timestampType = type.GetPropertyType(parameterPropertyStart); var getter = ((EventTypeSPI) type).GetGetterSPI(parameterPropertyStart); var getterReturnTypeBoxed = type.GetPropertyType(parameterPropertyStart).GetBoxedType(); ForgeTimestamp = new ExprEvaluatorStreamDTProp(parameterStreamNum, getter, getterReturnTypeBoxed); if (type.EndTimestampPropertyName != null) { parameterPropertyEnd = type.EndTimestampPropertyName; var getterEndTimestamp = ((EventTypeSPI) type).GetGetterSPI(type.EndTimestampPropertyName); forgeEndTimestamp = new ExprEvaluatorStreamDTProp( parameterStreamNum, getterEndTimestamp, getterReturnTypeBoxed); } else { parameterPropertyEnd = parameterPropertyStart; } } else { ForgeTimestamp = expressions[0].Forge; timestampType = ForgeTimestamp.EvaluationType; string unresolvedPropertyName = null; if (expressions[0] is ExprIdentNode) { var identNode = (ExprIdentNode) expressions[0]; parameterStreamNum = identNode.StreamId; parameterPropertyStart = identNode.ResolvedPropertyName; parameterPropertyEnd = parameterPropertyStart; unresolvedPropertyName = identNode.UnresolvedPropertyName; } if (!TypeHelper.IsDateTime(ForgeTimestamp.EvaluationType)) { // ident node may represent a fragment if (unresolvedPropertyName != null) { var propertyDesc = ExprIdentNodeUtil.GetTypeFromStream( streamTypeService, unresolvedPropertyName, false, true, tableCompileTimeResolver); if (propertyDesc.First.FragmentEventType != null) { var type = propertyDesc.First.FragmentEventType.FragmentType; parameterPropertyStart = type.StartTimestampPropertyName; if (parameterPropertyStart == null) { throw new ExprValidationException( "For date-time method '" + methodNameUse + "' the first parameter is event type '" + type.Name + "', however no timestamp property has been defined for this event type"); } timestampType = type.GetPropertyType(parameterPropertyStart); var getterFragment = ((EventTypeSPI) streamTypeService.EventTypes[parameterStreamNum]).GetGetterSPI( unresolvedPropertyName); var getterStartTimestamp = ((EventTypeSPI) type).GetGetterSPI(parameterPropertyStart); ForgeTimestamp = new ExprEvaluatorStreamDTPropFragment( parameterStreamNum, getterFragment, getterStartTimestamp); if (type.EndTimestampPropertyName != null) { parameterPropertyEnd = type.EndTimestampPropertyName; var getterEndTimestamp = ((EventTypeSPI) type).GetGetterSPI(type.EndTimestampPropertyName); forgeEndTimestamp = new ExprEvaluatorStreamDTPropFragment( parameterStreamNum, getterFragment, getterEndTimestamp); } else { parameterPropertyEnd = parameterPropertyStart; } } } else { throw new ExprValidationException( "For date-time method '" + methodNameUse + "' the first parameter expression returns '" + ForgeTimestamp.EvaluationType + "', however requires a Date, DateTimeEx, Long-type return value or event (with timestamp)"); } } } var intervalComputerForge = IntervalComputerForgeFactory.Make(method, expressions, timeAbacus); // evaluation without end timestamp var timestampTypeBoxed = timestampType.GetBoxedType(); if (forgeEndTimestamp == null) { if (TypeHelper.IsSubclassOrImplementsInterface(timestampType, typeof(DateTimeEx))) { IntervalOpForge = new IntervalOpDateTimeExForge(intervalComputerForge); } else if (timestampTypeBoxed == typeof(long?)) { IntervalOpForge = new IntervalOpForgeLong(intervalComputerForge); } else if (timestampTypeBoxed == typeof(DateTimeOffset?)) { IntervalOpForge = new IntervalOpDateTimeOffsetForge(intervalComputerForge); } else if (timestampTypeBoxed == typeof(DateTime?)) { IntervalOpForge = new IntervalOpDateTimeForge(intervalComputerForge); } else { throw new ArgumentException("Invalid interval first parameter type '" + timestampType + "'"); } } else { if (TypeHelper.IsSubclassOrImplementsInterface(timestampType, typeof(DateTimeEx))) { IntervalOpForge = new IntervalOpDateTimeExWithEndForge(intervalComputerForge, forgeEndTimestamp); } else if (timestampTypeBoxed == typeof(long?)) { IntervalOpForge = new IntervalOpLongWithEndForge(intervalComputerForge, forgeEndTimestamp); } else if (timestampTypeBoxed == typeof(DateTimeOffset?)) { IntervalOpForge = new IntervalOpDateTimeOffsetWithEndForge( intervalComputerForge, forgeEndTimestamp); } else if (timestampTypeBoxed == typeof(DateTime?)) { IntervalOpForge = new IntervalOpDateTimeWithEndForge(intervalComputerForge, forgeEndTimestamp); } else { throw new ArgumentException("Invalid interval first parameter type '" + timestampType + "'"); } } }