public void AddFunctionResolveWorksTest() { const string function = "add"; const EvaluationMode evaluationMode = EvaluationMode.Resolve; #region 1L + 1L var parameters1 = new ArrayList {1L, 1L}; var expressionFunction1 = new ExpressionFunction(function, parameters1, evaluationMode); Assert.IsNotNull(expressionFunction1); var result1 = expressionFunction1.Run(); Assert.IsNotNull(result1); Assert.IsInstanceOfType(result1, typeof(long)); Assert.AreEqual(2L, result1); #endregion #region 10L + 10L var parameters2 = new ArrayList { 10L, 10L }; var expressionFunction2 = new ExpressionFunction(function, parameters2, evaluationMode); Assert.IsNotNull(expressionFunction2); var result2 = expressionFunction2.Run(); Assert.IsNotNull(result2); Assert.IsInstanceOfType(result2, typeof(long)); Assert.AreEqual(20L, result2); #endregion }
/// <summary> /// Ejecuta una función a partir de una expresión /// </summary> internal async Task <VariableModel> ExecuteFunctionAsync(ExpressionFunction expression, CancellationToken cancellationToken) { VariableModel result = null; // Busca la función y la ejecuta if (string.IsNullOrWhiteSpace(expression.Function)) { AddError("Cant find the name funcion for call"); } else { BaseFunctionModel function = Context.Actual.FunctionsTable.GetIfExists(expression.Function); if (function == null) { AddError($"Cant find the function to call: {expression.Function}"); } else { result = await ExecuteFunctionAsync(function, expression.Arguments, true, cancellationToken); } } // Devuelve el resultado de la función return(result); }
/// <summary> /// Helper method to go find the value(s) of a property and put into a List<double> /// </summary> private double[] AddValuesToList(string SubPropertyName) { if (ArraySizeNumber == -1) { ArraySizeNumber = Convert.ToInt32(ExpressionFunction.Evaluate(ArraySize, My)); } double[] Values = new double[ArraySizeNumber]; int i = 0; foreach (string PropertyName in Propertys) { object Obj = Util.GetVariable(PropertyName + SubPropertyName, My); if (Obj == null) { throw new Exception("Cannot find: " + PropertyName + " in ArrayBiomass: " + My.Name); } if (Obj is IEnumerable) { foreach (object Value in Obj as IEnumerable) { Values[i] = Convert.ToDouble(Value); i++; } } else { Values[i] = Convert.ToDouble(Obj); i++; } } return(Values); }
public void AddFunctionResolveStringInvalidInputFormatTest() { const string function = "add"; const EvaluationMode evaluationMode = EvaluationMode.Resolve; #region 10 string + 10 string var parameters1 = new ArrayList { "10", "10" }; var expresssionFunction1 = new ExpressionFunction(function, parameters1, evaluationMode); expresssionFunction1.Run(); #endregion }
private IFunction[] GetFunctions() { IFunction[] functions = new IFunction[expressions.Length]; for (int i = 0; i < functions.Length; i++) { functions[i] = new ExpressionFunction(expressions[i]); } return(functions); }
public void AddFunctionResolveCharInvalidInputFormatTest() { const string function = "add"; const EvaluationMode evaluationMode = EvaluationMode.Resolve; #region 1 char + 1 char var parameters1 = new ArrayList { '1', '1' }; var expresssionFunction1 = new ExpressionFunction(function, parameters1, evaluationMode); expresssionFunction1.Run(); #endregion }
public static ExpressionResult ExecuteFunction(ExpressionFunction function) { ExpressionResult result = new ExpressionResult(); foreach (ExpressionFunctionArgument arg in function.Arguments) { ExpressionParser parser = new ExpressionParser(arg.ArgumentTokens); ExpressionResult argument = parser.Execute(); } return(result); }
private IFunction[] GetFunctions(string[] exp) { IFunction[] func = new IFunction[exp.Length]; for (int i = 0; i < func.Length; i++) { func[i] = new ExpressionFunction(exp[i]); if (i > 0 && func[i - 1].independent != func[i].independent) { throw new InvalidVariableException("Las funciones tienen que declarar la misma variable"); } } return(func); }
public virtual void Execute(bool isValidating = false) { if (ManualExecute) { return; } try { var startTime = DateTime.Now; //Evaluate parameters foreach (var parameter in Parameters) { parameter.Value.Execute(isValidating); } //Evaluate subexpression if (SubExpression != null) { SubExpression.Execute(isValidating); Value = SubExpression.Value; } //Evaluate ExpressionFunction if (ExpressionFunction != null) { Value = ExpressionFunction.Invoke(this); } //if (Logger.ShouldLog(Logger.Category.Trace, TraceEventType.Information)) //{ // Logger.Info(string.Format("{0} = {1}, cost {2} ms", FullKey, Value, (DateTime.Now - startTime).TotalMilliseconds)); //} //Validate value Validate(isValidating); } catch (ExpressionException ex) { throw new ExpressionException(string.Format("{0} has error:{1}", FullKey, ex.Message), ex) { Expression = ex.Expression }; } catch (Exception ex) { throw new ExpressionException(string.Format("{0} has error:{1}", FullKey, ex.Message), this.GetCommandName(), ex) { Expression = this }; } }
IExpression ParsePrimary() { IExpression result; var lex = _lexicalScanner.Current; switch (lex.Type) { case LexicalScanResultType.Numeric: result = new ExpressionLiteral(lex.Value); break; case LexicalScanResultType.Variable: result = new ExpressionVariable(lex.Value); break; case LexicalScanResultType.BracketOpen: result = ParseExpression(); if (_lexicalScanner.Current == null) { throw new IndexOutOfRangeException(); } else if (_lexicalScanner.Current.Type != LexicalScanResultType.BracketClose) { throw new NotSupportedException($"Not expected expression {_lexicalScanner.Current.Value}, expected ')'"); } break; case LexicalScanResultType.Function: var name = _lexicalScanner.Current.Value; var args = new List <IExpression>(); while (_lexicalScanner.Current != null && _lexicalScanner.Current.Type != LexicalScanResultType.BracketClose) { args.Add(ParseExpression()); } _lexicalScanner.Next(); result = new ExpressionFunction(name, args); break; default: throw new NotImplementedException(); } _lexicalScanner.Next(); return(result); }
private void AddFunctionToExpression(string signature) { signature = ExpressionFunction.PadSignature(signature); int start, end; if (ExpressionFunction.GetFirstArgumentWithinSignature(signature, out start, out end)) { int pos = txtExpression.SelectionStart; txtExpression.SelectedText = signature + " "; pos += start; int length = end - start + 1; txtExpression.Select(pos, length); } else { AddTextToExpression(signature); } }
/// <summary> /// Obtiene el valor de una función /// </summary> private string TransformExpressionFunction(ExpressionFunction expression) { string result = $"{expression.Function}("; // Añade las expresiones for (int index = 0; index < expression.Arguments.Count; index++) { // Añade el separador de parámetros if (index > 0) { result += ", "; } // Añade la expresión del argumento result += TransformExpressions(expression.Arguments[index]).TrimIgnoreNull(); } // Añade el paréntesis final result += ")"; // y devuelve el resultado return(result); }
/// <summary>Adds the values to list.</summary> /// <param name="SubPropertyName">Name of the sub property.</param> /// <returns></returns> /// <exception cref="System.Exception">Cannot find: + PropertyName + in ArrayBiomass: + this.Name</exception> private double[] AddValuesToList(string SubPropertyName) { if (ArraySizeNumber == -1) { ArraySizeNumber = Convert.ToInt32(ExpressionFunction.Evaluate(ArraySize, this), CultureInfo.InvariantCulture); } double[] Values = new double[ArraySizeNumber]; int i = 0; foreach (string PropertyName in Propertys) { object Obj = this.FindByPath(PropertyName + SubPropertyName)?.Value; if (Obj == null) { throw new Exception("Cannot find: " + PropertyName + " in ArrayBiomass: " + this.Name); } if (Obj is IEnumerable) { foreach (object Value in Obj as IEnumerable) { Values[i] = Convert.ToDouble(Value, System.Globalization.CultureInfo.InvariantCulture); i++; } } else { Values[i] = Convert.ToDouble(Obj, System.Globalization.CultureInfo.InvariantCulture); i++; } } return(Values); }
internal protected ODataExpression(ODataExpression caller, ExpressionFunction function) { _functionCaller = caller; Function = function; }
private static ExpressionResult CallFunction(ExpressionFunction function) { ExpressionResult result = new ExpressionResult(); return(result); }
public static bool TryGetOperatorMapping(ODataExpression functionCaller, ExpressionFunction function, AdapterVersion adapterVersion, out FunctionToOperatorMapping operatorMapping) { operatorMapping = DefinedMappings.SingleOrDefault(x => x.CanMap(function.FunctionName, function.Arguments.Count, functionCaller, adapterVersion)); return(operatorMapping != null); }
protected DynamicCommandExpression(CommandExpression caller, ExpressionFunction function) : base(caller, function) { }
protected DynamicCommandExpression(ExpressionFunction function) : base(function) { }
internal protected ODataExpression(ExpressionFunction function) { Function = function; }
protected DynamicODataExpression(ExpressionFunction function) : base(function) { }
protected DynamicODataExpression(ODataExpression caller, ExpressionFunction function) : base(caller, function) { }
/// <summary> /// Evaluates the function. /// </summary> /// <param name="function">The function.</param> /// <param name="mode">The mode.</param> /// <returns>The result of the evaluated function.</returns> private object EvaluateFunction(string function, EvaluationMode mode) { Logger.Instance.WriteMethodEntry(EventIdentifier.ExpressionEvaluatorEvaluateFunction, "Function: '{0}'. Evaluation Mode: '{1}'.", function, mode); object result = null; try { // Locate the opening and closing () characters for the function // by looking for the first and last instance of each character // This will ignore any nested functions which may be used as a parameter int open = function.IndexOf('('); int close = function.LastIndexOf(')'); // Break apart the function expression to identify the function name // and parameter string (content between parentheses) string functionName = function.Substring(0, open); string parameterString = function.Substring(open + 1, close - open - 1); // Create new array lists to hold the unresolved and resolved parameters for the function // Only evaluate parameters if the parameter string is not empty, as it will // be for functions like DateTimeNow() and Null() ArrayList unresolvedParameters = new ArrayList(); ArrayList parameters = new ArrayList(); if (!string.IsNullOrEmpty(parameterString.Trim())) { // The function expression could contain nested functions with their own commas // For example, Trim(Left(ReplaceString(attribute, "This", "That"), 8)) // Consequently, we can't assume that a split by comma returns each parameter // We need to loop through each and determine if a parameter needs to be reassembled // based on the positioning of ( and ) characters and quotation marks StringBuilder reassembled = new StringBuilder(); bool openString = false; int openFunctions = 0; // First, make sure that there are an appropriate number of ( and ) characters // and also make sure there is no open string in the function foreach (char c in parameterString) { if (c.Equals('\"')) { openString = !openString; } if (c.Equals('(') && !openString) { openFunctions += 1; } if (c.Equals(')') && !openString) { openFunctions -= 1; } } // If there is an open string or the number of open and close // parantheses characters do not match, throw an exception if (openString) { throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorEvaluateFunctionQuotesValidationError, new InvalidFunctionFormatException(Messages.ExpressionEvaluator_FunctionParameterQuotesValidationError, functionName)); } if (openFunctions != 0) { throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorEvaluateFunctionParenthesisValidationError, new InvalidFunctionFormatException(Messages.ExpressionEvaluator_FunctionParameterParenthesisValidationError, functionName)); } // Loop through each parameter fragment, split by comma, // and determine if reassembly is required foreach (string s in parameterString.Split(',')) { // Count the number of ( and ) characters in the current string // Only consider the parentheses relevent if it is not in an open string foreach (char c in s) { if (c.Equals('\"')) { openString = !openString; } else if (c.Equals('(') && !openString) { openFunctions += 1; } else if (c.Equals(')') && !openString) { openFunctions -= 1; } } // Add the string to the reassembled string builder // and determine how to proceed based on whether or not // we are currently reassembling parameter fragments reassembled.Append(s); if (openFunctions > 0 || openString) { reassembled.Append(","); } else { // If a parameter is not open, it either means that no // reassembly was required or we have completed reassembly // Either way, add the parameter to the list of unresolved parameters // and reset the string builder unresolvedParameters.Add(reassembled.ToString().Trim()); reassembled = new StringBuilder(); } } foreach (string s in unresolvedParameters) { Logger.Instance.WriteVerbose(EventIdentifier.ExpressionEvaluatorEvaluateFunction, "Resolving unresolved function parameter '{0}'.", s); ParameterType type = DetermineParameterType(s); switch (type) { case ParameterType.String: // Add the string value after trimming the quotes parameters.Add(EscapeString(s)); break; case ParameterType.Integer: // Add the parsed value as long as FIM datatype is System.Int64 parameters.Add(long.Parse(s, CultureInfo.InvariantCulture)); break; case ParameterType.Boolean: // Add the parsed Boolean value parameters.Add(bool.Parse(s)); break; case ParameterType.Lookup: if (mode == EvaluationMode.Parse) { // For parse, add the lookup to the cache // Mark the grammar in the parameter list by adding the appropriate enum value if (!this.lookupCache.ContainsKey(s)) { this.lookupCache.Add(s, null); } parameters.Add(ParameterType.Lookup); } else { // For resolution, pull the value from the lookup cache and // add it to the parameter list if (this.lookupCache.ContainsKey(s)) { parameters.Add(this.lookupCache[s]); } else { throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorEvaluateFunctionLookupCacheValidationError, new InvalidFunctionFormatException(Messages.ExpressionEvaluator_LookupCacheValidationError, s)); } } break; case ParameterType.Variable: if (mode == EvaluationMode.Parse) { // For parse, add the variable to the cache // Mark the variable in the parameter list by adding the appropriate enum value if (!this.variableCache.ContainsKey(s)) { this.variableCache.Add(s, null); } parameters.Add(ParameterType.Variable); } else { // For resolution, pull the value from the variable cache and // add it to the parameter list if (this.variableCache.ContainsKey(s)) { parameters.Add(this.variableCache[s]); } else { throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorEvaluateFunctionVariableCacheValidationError, new InvalidFunctionFormatException(Messages.ExpressionEvaluator_VariableCacheValidationError, s)); } } break; case ParameterType.Function: if (mode == EvaluationMode.Parse) { // For parse, recursively evaluate the function and any nested functions // Mark the function in the parameter list by adding the appropriate enum value this.EvaluateFunction(s, mode); parameters.Add(ParameterType.Function); } else { // For resolution, recursively resolve the function and any nested functions // and add the end result to the parameter list for the current function parameters.Add(this.EvaluateFunction(s, mode)); } break; case ParameterType.Expression: if (mode == EvaluationMode.Parse) { // For parse, recursively evaluate the expression and any nested functions // Mark the expression in the paramter list by adding the appropriate enum value this.EvaluateExpression(s, mode); parameters.Add(ParameterType.Expression); } else { // For resolution, recursively resolve the expression and any nested functions // and add the end result to the parameter list for the current function parameters.Add(this.EvaluateExpression(s, mode)); } break; default: throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorEvaluateFunctionParameterTypeValidationError, new InvalidFunctionFormatException()); } } } // Special handling for EvaluateExpression() function so that the lookups in the expression to evaluate are resolved // Assumption: the lookups used in the expression are already used in some other expressions // e.g. Consider [//Query/Site/xUserTemplateExpression] returning IIF(Eq([//Target/Department],"HR"),"Template1","Template2") // We want EvaluateExpression([//Query/Site/xUserTemplateExpression]). // In this case caller activity need to ensure that [//Target/Department] is already used any other expression // so that it's part of LookupCache. if (functionName.Equals(ParameterType.EvaluateExpression.ToString(), StringComparison.OrdinalIgnoreCase)) { Logger.Instance.WriteWarning(EventIdentifier.ExpressionEvaluatorEvaluateFunctionDeprecatedFunctionWarning, Messages.ExpressionFunction_DeprecatedFunctionWarning, ParameterType.EvaluateExpression.ToString(), "Resolve Dynamic Grammar capability of UpdateResources activity"); string expression = this.EvaluateExpression(parameterString, mode) as string; // so e.g. IIF(Eq([//Target/Department],"HR"),"Template1","Template2") if (mode != EvaluationMode.Parse && !string.IsNullOrEmpty(expression)) { // now evalaute the actual expression i.e. e.g. IIF(Eq([//Target/Department],"HR"),"Template1","Template2") result = this.EvaluateExpression(expression, mode); } } else { // Evaluate the function to make sure it is properly formatted, // all required parameters are available, and parameters are of the appropriate type // For most functions, the root value is allowed to be null to handle // scenarios when an attribute or expression is resolved to null // In this circumstance, an exception should not be thrown but the function should resolve to null ExpressionFunction expressionFunction = new ExpressionFunction(functionName, parameters, mode); result = expressionFunction.Run(); } return result; } finally { Logger.Instance.WriteMethodExit(EventIdentifier.ExpressionEvaluatorEvaluateFunction, "Function: '{0}'. Evaluation Mode: '{1}'. Returning: '{2}'.", function, mode, result); } }
internal static ODataExpression FromFunction(ExpressionFunction function) { return(new ODataExpression(function)); }