public ExprDotEvalVariable(ExprDotNode dotNode, VariableReader variableReader, ExprDotStaticMethodWrap resultWrapLambda, ExprDotEval[] chainEval) { _dotNode = dotNode; _variableReader = variableReader; _resultWrapLambda = resultWrapLambda; _chainEval = chainEval; }
public ExprDotNodeForgeStaticMethod( ExprNode parent, bool isReturnsConstantResult, string classOrPropertyName, MethodInfo staticMethod, ExprForge[] childForges, bool isConstantParameters, ExprDotForge[] chainForges, ExprDotStaticMethodWrap resultWrapLambda, bool rethrowExceptions, object targetObject, string optionalStatementName) { ExprForgeRenderable = parent; IsReturnsConstantResult = isReturnsConstantResult; ClassOrPropertyName = classOrPropertyName; StaticMethod = staticMethod; ChildForges = childForges; if (chainForges.Length > 0) { IsConstantParameters = false; } else { IsConstantParameters = isConstantParameters; } ChainForges = chainForges; ResultWrapLambda = resultWrapLambda; IsRethrowExceptions = rethrowExceptions; TargetObject = targetObject; OptionalStatementName = optionalStatementName; }
public static object EvaluateChainWithWrap( ExprDotStaticMethodWrap resultWrapLambda, object result, EventType optionalResultSingleEventType, Type resultType, ExprDotEval[] chainEval, ExprDotForge[] chainForges, EventBean[] eventsPerStream, bool newData, ExprEvaluatorContext exprEvaluatorContext) { if (result == null) { return(null); } if (resultWrapLambda != null) { result = resultWrapLambda.ConvertNonNull(result); } foreach (var aChainEval in chainEval) { result = aChainEval.Evaluate(result, eventsPerStream, newData, exprEvaluatorContext); if (result == null) { return(null); } } return(result); }
public ExprDotNodeForgeStaticMethod( ExprNode parent, bool isReturnsConstantResult, string classOrPropertyName, MethodInfo staticMethod, ExprForge[] childForges, bool isConstantParameters, ExprDotForge[] chainForges, ExprDotStaticMethodWrap resultWrapLambda, bool rethrowExceptions, ValueAndFieldDesc targetObject, string optionalStatementName, bool isLocalInlinedClass) { ExprForgeRenderable = parent; IsReturnsConstantResult = isReturnsConstantResult; ClassOrPropertyName = classOrPropertyName; StaticMethod = staticMethod; ChildForges = childForges; IsConstantParameters = chainForges.Length <= 0 && isConstantParameters; ChainForges = chainForges; ResultWrapLambda = resultWrapLambda; IsRethrowExceptions = rethrowExceptions; TargetObject = targetObject; OptionalStatementName = optionalStatementName; IsLocalInlinedClass = isLocalInlinedClass; }
public ExprDotNodeForgeVariable( ExprDotNodeImpl parent, VariableMetaData variable, ExprDotStaticMethodWrap resultWrapLambda, ExprDotForge[] chainForge) { ExprForgeRenderable = parent; Variable = variable; ResultWrapLambda = resultWrapLambda; ChainForge = chainForge; }
public ExprDotEvalStaticMethod(String statementName, String classOrPropertyName, FastMethod staticMethod, ExprEvaluator[] childEvals, bool constantParameters, ExprDotStaticMethodWrap resultWrapLambda, ExprDotEval[] chainEval, bool rethrowExceptions, Object targetObject) { _statementName = statementName; _classOrPropertyName = classOrPropertyName; _staticMethod = staticMethod; _childEvals = childEvals; _targetObject = targetObject; _isConstantParameters = chainEval.Length <= 0 && constantParameters; _resultWrapLambda = resultWrapLambda; _chainEval = chainEval; _rethrowExceptions = rethrowExceptions; }
public static object EvaluateChainWithWrap(ExprDotStaticMethodWrap resultWrapLambda, object result, EventType optionalResultSingleEventType, Type resultType, ExprDotEval[] chainEval, EventBean[] eventsPerStream, bool newData, ExprEvaluatorContext exprEvaluatorContext) { if (result == null) { return(null); } if (resultWrapLambda != null) { result = resultWrapLambda.Convert(result); } var evaluateParams = new EvaluateParams(eventsPerStream, newData, exprEvaluatorContext); if (InstrumentationHelper.ENABLED) { EPType typeInfo; if (resultWrapLambda != null) { typeInfo = resultWrapLambda.TypeInfo; } else { if (optionalResultSingleEventType != null) { typeInfo = EPTypeHelper.SingleEvent(optionalResultSingleEventType); } else { typeInfo = EPTypeHelper.SingleValue(resultType); } } InstrumentationHelper.Get().QExprDotChain(typeInfo, result, chainEval); var i = -1; foreach (var aChainEval in chainEval) { i++; InstrumentationHelper.Get().QExprDotChainElement(i, aChainEval); result = aChainEval.Evaluate(result, evaluateParams); InstrumentationHelper.Get().AExprDotChainElement(aChainEval.TypeInfo, result); if (result == null) { break; } } InstrumentationHelper.Get().AExprDotChain(); return(result); } foreach (var aChainEval in chainEval) { result = aChainEval.Evaluate(result, evaluateParams); if (result == null) { return(result); } } return(result); }
public override ExprNode Validate(ExprValidationContext validationContext) { // validate all parameters ExprNodeUtility.Validate(ExprNodeOrigin.DOTNODEPARAMETER, _chainSpec, validationContext); // determine if there are enumeration method expressions in the chain bool hasEnumerationMethod = false; foreach (ExprChainedSpec chain in _chainSpec) { if (chain.Name.IsEnumerationMethod()) { hasEnumerationMethod = true; break; } } // determine if there is an implied binding, replace first chain element with evaluation node if there is if (validationContext.StreamTypeService.HasTableTypes && validationContext.TableService != null && _chainSpec.Count > 1 && _chainSpec[0].IsProperty) { Pair <ExprNode, IList <ExprChainedSpec> > tableNode = validationContext.TableService.GetTableNodeChainable( validationContext.StreamTypeService, _chainSpec, validationContext.EngineImportService); if (tableNode != null) { ExprNode node = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.DOTNODE, tableNode.First, validationContext); if (tableNode.Second.IsEmpty()) { return(node); } _chainSpec.Clear(); _chainSpec.AddAll(tableNode.Second); AddChildNode(node); } } // The root node expression may provide the input value: // Such as "window(*).doIt(...)" or "(select * from Window).doIt()" or "prevwindow(sb).doIt(...)", in which case the expression to act on is a child expression // StreamTypeService streamTypeService = validationContext.StreamTypeService; if (ChildNodes.Length != 0) { // the root expression is the first child node ExprNode rootNode = ChildNodes[0]; ExprEvaluator rootNodeEvaluator = rootNode.ExprEvaluator; // the root expression may also provide a lambda-function input (GetEnumerator<EventBean>) // Determine collection-type and evaluator if any for root node ExprDotEnumerationSource enumSrc = ExprDotNodeUtility.GetEnumerationSource(rootNode, validationContext.StreamTypeService, validationContext.EventAdapterService, validationContext.StatementId, hasEnumerationMethod, validationContext.IsDisablePropertyExpressionEventCollCache); EPType typeInfo; if (enumSrc.ReturnType == null) { typeInfo = EPTypeHelper.SingleValue(rootNodeEvaluator.ReturnType); // not a collection type, treat as scalar } else { typeInfo = enumSrc.ReturnType; } ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(enumSrc.StreamOfProviderIfApplicable, typeInfo, _chainSpec, validationContext, _isDuckTyping, new ExprDotNodeFilterAnalyzerInputExpr()); _exprEvaluator = new ExprDotEvalRootChild(hasEnumerationMethod, this, rootNodeEvaluator, enumSrc.Enumeration, typeInfo, evals.Chain, evals.ChainWithUnpack, false); return(null); } // No root node, and this is a 1-element chain i.e. "something(param,...)". // Plug-in single-row methods are not handled here. // Plug-in aggregation methods are not handled here. if (_chainSpec.Count == 1) { ExprChainedSpec spec = _chainSpec[0]; if (spec.Parameters.IsEmpty()) { throw HandleNotFound(spec.Name); } // single-parameter can resolve to a property Pair <PropertyResolutionDescriptor, string> propertyInfoPair = null; try { propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, spec.Name, streamTypeService.HasPropertyAgnosticType, false); } catch (ExprValidationPropertyException) { // fine } // if not a property then try built-in single-row non-grammar functions if (propertyInfoPair == null && string.Equals(spec.Name, EngineImportServiceConstants.EXT_SINGLEROW_FUNCTION_TRANSPOSE, StringComparison.OrdinalIgnoreCase)) { if (spec.Parameters.Count != 1) { throw new ExprValidationException("The " + EngineImportServiceConstants.EXT_SINGLEROW_FUNCTION_TRANSPOSE + " function requires a single parameter expression"); } _exprEvaluator = new ExprDotEvalTransposeAsStream(_chainSpec[0].Parameters[0].ExprEvaluator); } else if (spec.Parameters.Count != 1) { throw HandleNotFound(spec.Name); } else { if (propertyInfoPair == null) { throw new ExprValidationException("Unknown single-row function, aggregation function or mapped or indexed property named '" + spec.Name + "' could not be resolved"); } _exprEvaluator = GetPropertyPairEvaluator(spec.Parameters[0].ExprEvaluator, propertyInfoPair, validationContext); _streamNumReferenced = propertyInfoPair.First.StreamNum; } return(null); } // handle the case where the first chain spec element is a stream name. ExprValidationException prefixedStreamNumException = null; int prefixedStreamNumber = PrefixedStreamName(_chainSpec, validationContext.StreamTypeService); if (prefixedStreamNumber != -1) { ExprChainedSpec specAfterStreamName = _chainSpec[1]; // Attempt to resolve as property Pair <PropertyResolutionDescriptor, string> propertyInfoPair = null; try { string propName = _chainSpec[0].Name + "." + specAfterStreamName.Name; propertyInfoPair = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, propName, streamTypeService.HasPropertyAgnosticType, false); } catch (ExprValidationPropertyException) { // fine } if (propertyInfoPair != null) { if (specAfterStreamName.Parameters.Count != 1) { throw HandleNotFound(specAfterStreamName.Name); } _exprEvaluator = GetPropertyPairEvaluator(specAfterStreamName.Parameters[0].ExprEvaluator, propertyInfoPair, validationContext); _streamNumReferenced = propertyInfoPair.First.StreamNum; return(null); } // Attempt to resolve as event-underlying object instance method EventType eventType = validationContext.StreamTypeService.EventTypes[prefixedStreamNumber]; Type type = eventType.UnderlyingType; IList <ExprChainedSpec> remainderChain = new List <ExprChainedSpec>(_chainSpec); remainderChain.RemoveAt(0); ExprValidationException methodEx = null; ExprDotEval[] underlyingMethodChain = null; try { EPType typeInfo = EPTypeHelper.SingleValue(type); underlyingMethodChain = ExprDotNodeUtility.GetChainEvaluators(prefixedStreamNumber, typeInfo, remainderChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber)).ChainWithUnpack; } catch (ExprValidationException ex) { methodEx = ex; // expected - may not be able to find the methods on the underlying } ExprDotEval[] eventTypeMethodChain = null; ExprValidationException enumDatetimeEx = null; try { EPType typeInfo = EPTypeHelper.SingleEvent(eventType); ExprDotNodeRealizedChain chain = ExprDotNodeUtility.GetChainEvaluators(prefixedStreamNumber, typeInfo, remainderChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStream(prefixedStreamNumber)); eventTypeMethodChain = chain.ChainWithUnpack; _exprDotNodeFilterAnalyzerDesc = chain.FilterAnalyzerDesc; } catch (ExprValidationException ex) { enumDatetimeEx = ex; // expected - may not be able to find the methods on the underlying } if (underlyingMethodChain != null) { _exprEvaluator = new ExprDotEvalStreamMethod(this, prefixedStreamNumber, underlyingMethodChain); _streamNumReferenced = prefixedStreamNumber; } else if (eventTypeMethodChain != null) { _exprEvaluator = new ExprDotEvalStreamEventBean(this, prefixedStreamNumber, eventTypeMethodChain); _streamNumReferenced = prefixedStreamNumber; } if (_exprEvaluator != null) { return(null); } else { if (ExprDotNodeUtility.IsDatetimeOrEnumMethod(remainderChain[0].Name)) { prefixedStreamNumException = enumDatetimeEx; } else { prefixedStreamNumException = new ExprValidationException("Failed to solve '" + remainderChain[0].Name + "' to either a date-time or enumeration method, an event property or a method on the event underlying object: " + methodEx.Message, methodEx); } } } // There no root node, in this case the classname or property name is provided as part of the chain. // Such as "MyClass.myStaticLib(...)" or "mycollectionproperty.doIt(...)" // IList <ExprChainedSpec> modifiedChain = new List <ExprChainedSpec>(_chainSpec); ExprChainedSpec firstItem = modifiedChain.Delete(0); Pair <PropertyResolutionDescriptor, string> propertyInfoPairX = null; try { propertyInfoPairX = ExprIdentNodeUtil.GetTypeFromStream(streamTypeService, firstItem.Name, streamTypeService.HasPropertyAgnosticType, true); } catch (ExprValidationPropertyException) { // not a property } // If property then treat it as such if (propertyInfoPairX != null) { string propertyName = propertyInfoPairX.First.PropertyName; int streamId = propertyInfoPairX.First.StreamNum; EventType streamType = streamTypeService.EventTypes[streamId]; EPType typeInfo; ExprEvaluatorEnumeration enumerationEval = null; EPType inputType; ExprEvaluator rootNodeEvaluator = null; EventPropertyGetter getter; if (firstItem.Parameters.IsEmpty()) { getter = streamType.GetGetter(propertyInfoPairX.First.PropertyName); ExprDotEnumerationSourceForProps propertyEval = ExprDotNodeUtility.GetPropertyEnumerationSource( propertyInfoPairX.First.PropertyName, streamId, streamType, hasEnumerationMethod, validationContext.IsDisablePropertyExpressionEventCollCache); typeInfo = propertyEval.ReturnType; enumerationEval = propertyEval.Enumeration; inputType = propertyEval.ReturnType; rootNodeEvaluator = new PropertyExprEvaluatorNonLambda(streamId, getter, propertyInfoPairX.First.PropertyType); } else { // property with parameter - mapped or indexed property EventPropertyDescriptor desc = EventTypeUtility.GetNestablePropertyDescriptor(streamTypeService.EventTypes[propertyInfoPairX.First.StreamNum], firstItem.Name); if (firstItem.Parameters.Count > 1) { throw new ExprValidationException("Property '" + firstItem.Name + "' may not be accessed passing 2 or more parameters"); } ExprEvaluator paramEval = firstItem.Parameters[0].ExprEvaluator; typeInfo = EPTypeHelper.SingleValue(desc.PropertyComponentType); inputType = typeInfo; getter = null; if (desc.IsMapped) { if (paramEval.ReturnType != typeof(string)) { throw new ExprValidationException("Parameter expression to mapped property '" + propertyName + "' is expected to return a string-type value but returns " + paramEval.ReturnType.GetTypeNameFullyQualPretty()); } EventPropertyGetterMapped mappedGetter = propertyInfoPairX.First.StreamEventType.GetGetterMapped(propertyInfoPairX.First.PropertyName); if (mappedGetter == null) { throw new ExprValidationException("Mapped property named '" + propertyName + "' failed to obtain getter-object"); } rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaMapped(streamId, mappedGetter, paramEval, desc.PropertyComponentType); } if (desc.IsIndexed) { if (paramEval.ReturnType.GetBoxedType() != typeof(int?)) { throw new ExprValidationException("Parameter expression to mapped property '" + propertyName + "' is expected to return a Integer-type value but returns " + paramEval.ReturnType.GetTypeNameFullyQualPretty()); } EventPropertyGetterIndexed indexedGetter = propertyInfoPairX.First.StreamEventType.GetGetterIndexed(propertyInfoPairX.First.PropertyName); if (indexedGetter == null) { throw new ExprValidationException("Mapped property named '" + propertyName + "' failed to obtain getter-object"); } rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaIndexed(streamId, indexedGetter, paramEval, desc.PropertyComponentType); } } if (typeInfo == null) { throw new ExprValidationException("Property '" + propertyName + "' is not a mapped or indexed property"); } // try to build chain based on the input (non-fragment) ExprDotNodeRealizedChain evals; ExprDotNodeFilterAnalyzerInputProp filterAnalyzerInputProp = new ExprDotNodeFilterAnalyzerInputProp(propertyInfoPairX.First.StreamNum, propertyInfoPairX.First.PropertyName); bool rootIsEventBean = false; try { evals = ExprDotNodeUtility.GetChainEvaluators(streamId, inputType, modifiedChain, validationContext, _isDuckTyping, filterAnalyzerInputProp); } catch (ExprValidationException ex) { // try building the chain based on the fragment event type (i.e. A.after(B) based on A-configured start time where A is a fragment) FragmentEventType fragment = propertyInfoPairX.First.FragmentEventType; if (fragment == null) { throw; } EPType fragmentTypeInfo; if (fragment.IsIndexed) { fragmentTypeInfo = EPTypeHelper.CollectionOfEvents(fragment.FragmentType); } else { fragmentTypeInfo = EPTypeHelper.SingleEvent(fragment.FragmentType); } rootIsEventBean = true; evals = ExprDotNodeUtility.GetChainEvaluators(propertyInfoPairX.First.StreamNum, fragmentTypeInfo, modifiedChain, validationContext, _isDuckTyping, filterAnalyzerInputProp); rootNodeEvaluator = new PropertyExprEvaluatorNonLambdaFragment(streamId, getter, fragment.FragmentType.UnderlyingType); } _exprEvaluator = new ExprDotEvalRootChild(hasEnumerationMethod, this, rootNodeEvaluator, enumerationEval, inputType, evals.Chain, evals.ChainWithUnpack, !rootIsEventBean); _exprDotNodeFilterAnalyzerDesc = evals.FilterAnalyzerDesc; _streamNumReferenced = propertyInfoPairX.First.StreamNum; _rootPropertyName = propertyInfoPairX.First.PropertyName; return(null); } // If variable then resolve as such string contextNameVariable = validationContext.VariableService.IsContextVariable(firstItem.Name); if (contextNameVariable != null) { throw new ExprValidationException("Method invocation on context-specific variable is not supported"); } VariableReader variableReader = validationContext.VariableService.GetReader(firstItem.Name, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID); if (variableReader != null) { EPType typeInfo; ExprDotStaticMethodWrap wrap; if (variableReader.VariableMetaData.VariableType.IsArray) { typeInfo = EPTypeHelper.CollectionOfSingleValue(variableReader.VariableMetaData.VariableType.GetElementType()); wrap = new ExprDotStaticMethodWrapArrayScalar(variableReader.VariableMetaData.VariableName, variableReader.VariableMetaData.VariableType.GetElementType()); } else if (variableReader.VariableMetaData.EventType != null) { typeInfo = EPTypeHelper.SingleEvent(variableReader.VariableMetaData.EventType); wrap = null; } else { typeInfo = EPTypeHelper.SingleValue(variableReader.VariableMetaData.VariableType); wrap = null; } ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(null, typeInfo, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic()); _exprEvaluator = new ExprDotEvalVariable(this, variableReader, wrap, evals.ChainWithUnpack); return(null); } // try resolve as enumeration class with value object enumconstant = TypeHelper.ResolveIdentAsEnumConst(firstItem.Name, validationContext.EngineImportService, false); if (enumconstant != null) { // try resolve method ExprChainedSpec methodSpec = modifiedChain[0]; string enumvalue = firstItem.Name; ExprNodeUtilResolveExceptionHandler handler = new ProxyExprNodeUtilResolveExceptionHandler { ProcHandle = ex => new ExprValidationException("Failed to resolve method '" + methodSpec.Name + "' on enumeration value '" + enumvalue + "': " + ex.Message), }; EventType wildcardType = validationContext.StreamTypeService.EventTypes.Length != 1 ? null : validationContext.StreamTypeService.EventTypes[0]; ExprNodeUtilMethodDesc methodDesc = ExprNodeUtility.ResolveMethodAllowWildcardAndStream( enumconstant.GetType().Name, enumconstant.GetType(), methodSpec.Name, methodSpec.Parameters, validationContext.EngineImportService, validationContext.EventAdapterService, validationContext.StatementId, wildcardType != null, wildcardType, handler, methodSpec.Name, validationContext.TableService); // method resolved, hook up modifiedChain.RemoveAt(0); // we identified this piece ExprDotStaticMethodWrap optionalLambdaWrap = ExprDotStaticMethodWrapFactory.Make(methodDesc.ReflectionMethod, validationContext.EventAdapterService, modifiedChain); EPType typeInfo = optionalLambdaWrap != null ? optionalLambdaWrap.TypeInfo : EPTypeHelper.SingleValue(methodDesc.FastMethod.ReturnType); ExprDotNodeRealizedChain evals = ExprDotNodeUtility.GetChainEvaluators(null, typeInfo, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic()); _exprEvaluator = new ExprDotEvalStaticMethod(validationContext.StatementName, firstItem.Name, methodDesc.FastMethod, methodDesc.ChildEvals, false, optionalLambdaWrap, evals.ChainWithUnpack, false, enumconstant); return(null); } // if prefixed by a stream name, we are giving up if (prefixedStreamNumException != null) { throw prefixedStreamNumException; } // If class then resolve as class ExprChainedSpec secondItem = modifiedChain.Delete(0); bool allowWildcard = validationContext.StreamTypeService.EventTypes.Length == 1; EventType streamZeroType = null; if (validationContext.StreamTypeService.EventTypes.Length > 0) { streamZeroType = validationContext.StreamTypeService.EventTypes[0]; } ExprNodeUtilMethodDesc method = ExprNodeUtility.ResolveMethodAllowWildcardAndStream( firstItem.Name, null, secondItem.Name, secondItem.Parameters, validationContext.EngineImportService, validationContext.EventAdapterService, validationContext.StatementId, allowWildcard, streamZeroType, new ExprNodeUtilResolveExceptionHandlerDefault(firstItem.Name + "." + secondItem.Name, false), secondItem.Name, validationContext.TableService); bool isConstantParameters = method.IsAllConstants && _isUDFCache; _isReturnsConstantResult = isConstantParameters && modifiedChain.IsEmpty(); // this may return a pair of null if there is no lambda or the result cannot be wrapped for lambda-function use ExprDotStaticMethodWrap optionalLambdaWrapX = ExprDotStaticMethodWrapFactory.Make(method.ReflectionMethod, validationContext.EventAdapterService, modifiedChain); EPType typeInfoX = optionalLambdaWrapX != null ? optionalLambdaWrapX.TypeInfo : EPTypeHelper.SingleValue(method.ReflectionMethod.ReturnType); ExprDotNodeRealizedChain evalsX = ExprDotNodeUtility.GetChainEvaluators(null, typeInfoX, modifiedChain, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic()); _exprEvaluator = new ExprDotEvalStaticMethod(validationContext.StatementName, firstItem.Name, method.FastMethod, method.ChildEvals, isConstantParameters, optionalLambdaWrapX, evalsX.ChainWithUnpack, false, null); return(null); }
public override ExprNode Validate(ExprValidationContext validationContext) { ExprNodeUtilityValidate.Validate(ExprNodeOrigin.PLUGINSINGLEROWPARAM, ChainSpec, validationContext); // get first chain item IList<ExprChainedSpec> chainList = new List<ExprChainedSpec>(ChainSpec); var firstItem = chainList.DeleteAt(0); // Get the types of the parameters for the first invocation var allowWildcard = validationContext.StreamTypeService.EventTypes.Length == 1; EventType streamZeroType = null; if (validationContext.StreamTypeService.EventTypes.Length > 0) { streamZeroType = validationContext.StreamTypeService.EventTypes[0]; } var staticMethodDesc = ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream( clazz.FullName, null, firstItem.Name, firstItem.Parameters, allowWildcard, streamZeroType, new ExprNodeUtilResolveExceptionHandlerDefault(firstItem.Name, true), FunctionName, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); var allowValueCache = true; bool isReturnsConstantResult; switch (config.ValueCache) { case ConfigurationCompilerPlugInSingleRowFunction.ValueCacheEnum.DISABLED: isReturnsConstantResult = false; allowValueCache = false; break; case ConfigurationCompilerPlugInSingleRowFunction.ValueCacheEnum.CONFIGURED: { var isUDFCache = validationContext.StatementCompileTimeService.Configuration.Compiler.Expression .IsUdfCache; isReturnsConstantResult = isUDFCache && staticMethodDesc.IsAllConstants && chainList.IsEmpty(); allowValueCache = isUDFCache; break; } case ConfigurationCompilerPlugInSingleRowFunction.ValueCacheEnum.ENABLED: isReturnsConstantResult = staticMethodDesc.IsAllConstants && chainList.IsEmpty(); break; default: throw new IllegalStateException("Invalid value cache code " + config.ValueCache); } // this may return a pair of null if there is no lambda or the result cannot be wrapped for lambda-function use ExprDotStaticMethodWrap optionalLambdaWrap = ExprDotStaticMethodWrapFactory.Make( staticMethodDesc.ReflectionMethod, chainList, config.OptionalEventTypeName, validationContext); var typeInfo = optionalLambdaWrap != null ? optionalLambdaWrap.TypeInfo : EPTypeHelper.SingleValue(staticMethodDesc.ReflectionMethod.ReturnType); var eval = ExprDotNodeUtility.GetChainEvaluators( -1, typeInfo, chainList, validationContext, false, new ExprDotNodeFilterAnalyzerInputStatic()) .ChainWithUnpack; var staticMethodForge = new ExprDotNodeForgeStaticMethod( this, isReturnsConstantResult, clazz.Name, staticMethodDesc.ReflectionMethod, staticMethodDesc.ChildForges, allowValueCache && staticMethodDesc.IsAllConstants, eval, optionalLambdaWrap, config.IsRethrowExceptions, null, validationContext.StatementName); // If caching the result, evaluate now and return the result. if (isReturnsConstantResult) { forge = new ExprPlugInSingleRowNodeForgeConst(this, staticMethodForge); } else { forge = new ExprPlugInSingleRowNodeForgeNC(this, staticMethodForge); } return null; }
public static CodegenExpression EvaluateChainCodegen( CodegenMethod parent, ExprForgeCodegenSymbol exprSymbol, CodegenClassScope codegenClassScope, CodegenExpression inner, Type innerType, ExprDotForge[] forges, ExprDotStaticMethodWrap optionalResultWrapLambda) { if (forges.Length == 0) { return inner; } var last = forges[forges.Length - 1]; var lastType = EPTypeHelper.GetCodegenReturnType(last.TypeInfo).GetBoxedType(); var methodNode = parent .MakeChild(lastType, typeof(ExprDotNodeUtility), codegenClassScope) .AddParam(innerType, "inner"); var block = methodNode.Block.DebugStack(); var currentTarget = "wrapped"; Type currentTargetType; if (optionalResultWrapLambda != null) { currentTargetType = EPTypeHelper.GetCodegenReturnType(optionalResultWrapLambda.TypeInfo); var wrapped = optionalResultWrapLambda.CodegenConvertNonNull(Ref("inner"), methodNode, codegenClassScope); if (currentTargetType == typeof(FlexCollection)) { wrapped = FlexWrap(wrapped); } block .IfRefNullReturnNull("inner") .DeclareVar(currentTargetType, "wrapped", wrapped); } else if (innerType == typeof(FlexCollection)) { block.DeclareVar(innerType, "wrapped", FlexWrap(Ref("inner"))); currentTargetType = innerType; } else { block.DeclareVar(innerType, "wrapped", Ref("inner")); currentTargetType = innerType; } string refname = null; var instrumentationName = new ExprDotEvalVisitorImpl(); for (var i = 0; i < forges.Length; i++) { refname = "r" + i; forges[i].Visit(instrumentationName); block.Apply( Instblock( codegenClassScope, "qExprDotChainElement", Constant(i), Constant(instrumentationName.MethodType), Constant(instrumentationName.MethodName))); var typeInformation = ConstantNull(); if (codegenClassScope.IsInstrumented) { typeInformation = codegenClassScope.AddOrGetDefaultFieldSharable( new EPTypeCodegenSharable(forges[i].TypeInfo, codegenClassScope)); } var reftype = forges[i].TypeInfo.GetCodegenReturnType().GetBoxedType(); if (reftype == typeof(void)) { block.Expression( forges[i] .Codegen( Ref(currentTarget), currentTargetType, methodNode, exprSymbol, codegenClassScope)) .Apply(Instblock(codegenClassScope, "aExprDotChainElement", typeInformation, ConstantNull())); } else { var invocation = forges[i] .Codegen( Ref(currentTarget), currentTargetType, methodNode, exprSymbol, codegenClassScope); // We can't assume anything about the return type. Unfortunately, we do not know the resultant type // of the forge... I must fix this. - TBD invocation = CodegenLegoCast.CastSafeFromObjectType(reftype, invocation); block.DeclareVar(reftype, refname, invocation); currentTarget = refname; currentTargetType = reftype; if (reftype.CanBeNull()) { block.IfRefNull(refname) .Apply( Instblock(codegenClassScope, "aExprDotChainElement", typeInformation, ConstantNull())) .BlockReturn(ConstantNull()); } block.Apply(Instblock(codegenClassScope, "aExprDotChainElement", typeInformation, Ref(refname))); } } if (lastType == typeof(void)) { block.MethodEnd(); } else { block.MethodReturn(Ref(refname)); } return LocalMethod(methodNode, inner); }