public void FilterAssignStartWithAccumulateBy(IGraphProcessingEnvironment procEnv, IList <IMatch> matchList, FilterCallWithLambdaExpression filterCall) { List <IMatch> matchListCopy = null; if (filterCall.initArrayAccess != null || filterCall.arrayAccess != null) { matchListCopy = new List <IMatch>(); foreach (IMatch match in matchList) { matchListCopy.Add(match.Clone()); } } if (filterCall.initArrayAccess != null) { filterCall.initArrayAccess.SetVariableValue(matchListCopy, procEnv); } if (filterCall.arrayAccess != null) { filterCall.arrayAccess.SetVariableValue(matchListCopy, procEnv); } filterCall.previousAccumulationAccess.SetVariableValue(filterCall.initExpression.Evaluate(procEnv), procEnv); for (int index = 0; index < matchList.Count; ++index) { if (filterCall.index != null) { filterCall.index.SetVariableValue(index, procEnv); } IMatch match = matchList[index]; filterCall.element.SetVariableValue(match, procEnv); object result = filterCall.lambdaExpression.Evaluate(procEnv); match.SetMember(filterCall.Entity, result); filterCall.previousAccumulationAccess.SetVariableValue(result, procEnv); } }
public void FilterRemoveIf(IGraphProcessingEnvironment procEnv, IList <IMatch> matchList, FilterCallWithLambdaExpression filterCall) { List <IMatch> matchListCopy = new List <IMatch>(matchList); if (filterCall.arrayAccess != null) { filterCall.arrayAccess.SetVariableValue(matchListCopy, procEnv); } matchList.Clear(); for (int index = 0; index < matchListCopy.Count; ++index) { if (filterCall.index != null) { filterCall.index.SetVariableValue(index, procEnv); } IMatch match = matchListCopy[index]; filterCall.element.SetVariableValue(match, procEnv); object result = filterCall.lambdaExpression.Evaluate(procEnv); if (!(bool)result) { matchList.Add(match); } } }
/// <summary> /// Checks whether called match class filter exists, and type checks the inputs. /// </summary> public void CheckMatchClassFilterCalls(List <SequenceFilterCallBase> sequenceFilterCalls, List <SequenceRuleCall> ruleCalls) { foreach (SequenceFilterCallBase sequenceFilterCallBase in sequenceFilterCalls) { String matchClassName = GetMatchClassName(sequenceFilterCallBase); foreach (SequenceRuleCall ruleCall in ruleCalls) { if (!IsRuleImplementingMatchClass(ruleCall.PackagePrefixedName, matchClassName)) { throw new SequenceParserException(matchClassName, ruleCall.PackagePrefixedName, SequenceParserError.MatchClassNotImplementedError); } } if (sequenceFilterCallBase is SequenceFilterCall) { SequenceFilterCall sequenceFilterCall = (SequenceFilterCall)sequenceFilterCallBase; String filterCallName = GetFilterCallName(sequenceFilterCall); // Check whether number of filter parameters match if (NumFilterFunctionParameters(sequenceFilterCall) != sequenceFilterCall.ArgumentExpressions.Length) { throw new SequenceParserException(matchClassName, filterCallName, SequenceParserError.FilterParameterError); } // Check parameter types for (int i = 0; i < sequenceFilterCall.ArgumentExpressions.Length; i++) { sequenceFilterCall.ArgumentExpressions[i].Check(this); String argumentType = sequenceFilterCall.ArgumentExpressions[i].Type(this); String paramterType = FilterFunctionParameterType(i, sequenceFilterCall); if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(matchClassName, filterCallName, SequenceParserError.FilterParameterError); } } } else { SequenceFilterCallLambdaExpression sequenceFilterCallLambdaExpression = (SequenceFilterCallLambdaExpression)sequenceFilterCallBase; String filterCallName = GetFilterCallName(sequenceFilterCallLambdaExpression); FilterCallWithLambdaExpression filterCall = sequenceFilterCallLambdaExpression.FilterCall; if (filterCall.initArrayAccess != null) { String argumentType = filterCall.initArrayAccess.Type; String paramterType = "array<match<class " + matchClassName + ">>"; if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(matchClassName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } if (filterCall.initExpression != null) { filterCall.initExpression.Check(this); } if (filterCall.arrayAccess != null) { String argumentType = filterCall.arrayAccess.Type; String paramterType = "array<match<class " + matchClassName + ">>"; if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(matchClassName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } if (filterCall.previousAccumulationAccess != null) { String argumentType = filterCall.previousAccumulationAccess.Type; String paramterType = TypeOfMemberOrAttribute("match<class " + matchClassName + ">", filterCall.Entity); if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(matchClassName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } if (filterCall.index != null) { String argumentType = filterCall.index.Type; String paramterType = "int"; if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(matchClassName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } String elementArgumentType = filterCall.element.Type; String elementParamterType = "match<class " + matchClassName + ">"; if (!TypesHelper.IsSameOrSubtype(elementArgumentType, elementParamterType, Model)) { throw new SequenceParserException(matchClassName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } filterCall.lambdaExpression.Check(this); } } }
/// <summary> /// Filters the matches of a multi rule all call or multi rule backtracking construct /// (i.e. matches obtained from different rules, that implement a match class) /// with a lambda expression filter (call). /// </summary> /// <param name="procEnv">The graph processing environment, required by the filter implementation.</param> /// <param name="matches">The combined list of all matches of all rules (implementing the same match class; to inspect and filter)</param> /// <param name="filter">The lambda expression filter to apply</param> public void Filter(IGraphProcessingEnvironment procEnv, IList <IMatch> matches, FilterCallWithLambdaExpression filter) { if (filter.PlainName == "assign") { FilterAssign(procEnv, matches, filter); } else if (filter.PlainName == "removeIf") { FilterRemoveIf(procEnv, matches, filter); } else if (filter.PlainName == "assignStartWithAccumulateBy") { FilterAssignStartWithAccumulateBy(procEnv, matches, filter); } else { throw new Exception("Unknown lambda expression filter call (available are assign, removeIf, assignStartWithAccumulateBy)"); } }
/// <summary> /// Checks whether called filter exists, and type checks the inputs. /// </summary> private void CheckFilterCalls(String ruleName, List <SequenceFilterCallBase> sequenceFilterCalls) { foreach (SequenceFilterCallBase sequenceFilterCallBase in sequenceFilterCalls) { if (sequenceFilterCallBase is SequenceFilterCall) { SequenceFilterCall sequenceFilterCall = (SequenceFilterCall)sequenceFilterCallBase; String filterCallName = GetFilterCallName(sequenceFilterCall); // Check whether number of filter parameters match if (NumFilterFunctionParameters(sequenceFilterCall) != sequenceFilterCall.ArgumentExpressions.Length) { throw new SequenceParserException(ruleName, filterCallName, SequenceParserError.FilterParameterError); } // Check parameter types for (int i = 0; i < sequenceFilterCall.ArgumentExpressions.Length; i++) { sequenceFilterCall.ArgumentExpressions[i].Check(this); String argumentType = sequenceFilterCall.ArgumentExpressions[i].Type(this); String paramterType = FilterFunctionParameterType(i, sequenceFilterCall); if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(ruleName, filterCallName, SequenceParserError.FilterParameterError); } } } else { SequenceFilterCallLambdaExpression sequenceFilterCallLambdaExpression = (SequenceFilterCallLambdaExpression)sequenceFilterCallBase; String filterCallName = GetFilterCallName(sequenceFilterCallLambdaExpression); FilterCallWithLambdaExpression filterCall = sequenceFilterCallLambdaExpression.FilterCall; if (filterCall.initArrayAccess != null) { String argumentType = filterCall.initArrayAccess.Type; String paramterType = "array<match<" + ruleName + ">>"; if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(ruleName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } if (filterCall.initExpression != null) { filterCall.initExpression.Check(this); } if (filterCall.arrayAccess != null) { String argumentType = filterCall.arrayAccess.Type; String paramterType = "array<match<" + ruleName + ">>"; if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(ruleName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } if (filterCall.previousAccumulationAccess != null) { String argumentType = filterCall.previousAccumulationAccess.Type; String paramterType = TypeOfTopLevelEntityInRule(ruleName, filterCall.Entity); if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(ruleName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } if (filterCall.index != null) { String argumentType = filterCall.index.Type; String paramterType = "int"; if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(ruleName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } } String elementArgumentType = filterCall.element.Type; String elementParamterType = "match<" + ruleName + ">"; if (!TypesHelper.IsSameOrSubtype(elementArgumentType, elementParamterType, Model)) { throw new SequenceParserException(ruleName, filterCallName, SequenceParserError.FilterLambdaExpressionError); } filterCall.lambdaExpression.Check(this); } } }