private void CheckSubgraph(Invocation invocation) { SequenceVariable subgraph; if (invocation is RuleInvocation) { RuleInvocation ruleInvocation = (RuleInvocation)invocation; subgraph = ruleInvocation.Subgraph; } else { SequenceInvocation sequenceInvocation = (SequenceInvocation)invocation; subgraph = sequenceInvocation.Subgraph; } if (subgraph != null && !TypesHelper.IsSameOrSubtype("graph", subgraph.Type, Model)) { throw new SequenceParserException(invocation.Name, subgraph.Type, SequenceParserError.SubgraphTypeError); } }
private void CheckOutputParameters(Invocation invocation, SequenceVariable[] ReturnVars, InheritanceType ownerType) { // Check whether number of parameters and return parameters match if (ReturnVars.Length != 0 && NumOutputParameters(invocation, ownerType) != ReturnVars.Length) { throw new SequenceParserException(invocation, ReturnVars.Length, SequenceParserError.BadNumberOfReturnParameters); } // Check return types for (int i = 0; i < ReturnVars.Length; ++i) { String argumentType = ReturnVars[i].Type; String paramterType = OutputParameterType(i, invocation, ownerType); if (!TypesHelper.IsSameOrSubtype(paramterType, argumentType, Model)) { throw new SequenceParserException(invocation, -1, SequenceParserError.BadReturnParameter, i); } } }
private void CheckInputParameters(Invocation invocation, SequenceExpression[] ArgumentExpressions, GrGenType ownerType) { // Check whether number of parameters and return parameters match if (NumInputParameters(invocation, ownerType) != ArgumentExpressions.Length) { throw new SequenceParserException(invocation, ArgumentExpressions.Length, SequenceParserError.BadNumberOfParameters); } // Check parameter types for (int i = 0; i < ArgumentExpressions.Length; i++) { ArgumentExpressions[i].Check(this); String argumentType = ArgumentExpressions[i].Type(this); String paramterType = InputParameterType(i, invocation, ownerType); if (!TypesHelper.IsSameOrSubtype(argumentType, paramterType, Model)) { throw new SequenceParserException(invocation, -1, SequenceParserError.BadParameter, i); } } }
public override void Check(SequenceCheckingEnvironment env) { base.Check(env); if (DestVar.Type == "") { return; // we can't gain access to an attribute type if the variable is untyped, only runtime-check possible } GrGenType nodeOrEdgeType = TypesHelper.GetNodeOrEdgeType(DestVar.Type, env.Model); if (nodeOrEdgeType == null) { throw new SequenceParserException(Symbol, "node or edge type", DestVar.Type); } AttributeType attributeType = nodeOrEdgeType.GetAttributeType(AttributeName); if (attributeType == null) { throw new SequenceParserException(AttributeName, SequenceParserError.UnknownAttribute); } }
public override void Check(SequenceCheckingEnvironment env) { base.Check(env); if (DestVar.Type == "") { return; // we can't gain access to an attribute type if the variable is untyped, only runtime-check possible } InheritanceType inheritanceType = TypesHelper.GetInheritanceType(DestVar.Type, env.Model); if (inheritanceType == null) { throw new SequenceParserException(Symbol, "node or edge or object or transient object type (class)", DestVar.Type); } AttributeType attributeType = inheritanceType.GetAttributeType(AttributeName); if (attributeType == null) { throw new SequenceParserException(AttributeName, SequenceParserError.UnknownAttribute); } }
protected override string InputParameterType(int i, Invocation invocation, GrGenType ownerType) { if (invocation is RuleInvocation) { RuleInvocation ruleInvocation = (RuleInvocation)invocation; return(actionsTypeInformation.rulesToInputTypes[ruleInvocation.PackagePrefixedName][i]); } else if (invocation is SequenceInvocation) { SequenceInvocation seqInvocation = (SequenceInvocation)invocation; return(actionsTypeInformation.sequencesToInputTypes[seqInvocation.PackagePrefixedName][i]); } else if (invocation is ProcedureInvocation) { ProcedureInvocation procInvocation = (ProcedureInvocation)invocation; if (ownerType != null) { IProcedureDefinition procDef = ownerType.GetProcedureMethod(procInvocation.Name); return(TypesHelper.DotNetTypeToXgrsType(procDef.Inputs[i])); } else { return(actionsTypeInformation.proceduresToInputTypes[procInvocation.PackagePrefixedName][i]); } } else if (invocation is FunctionInvocation) { FunctionInvocation funcInvocation = (FunctionInvocation)invocation; if (ownerType != null) { IFunctionDefinition funcDef = ownerType.GetFunctionMethod(funcInvocation.Name); return(TypesHelper.DotNetTypeToXgrsType(funcDef.Inputs[i])); } else { return(actionsTypeInformation.functionsToInputTypes[funcInvocation.PackagePrefixedName][i]); } } throw new Exception("Internal error"); }
/// <summary> /// Returns a string representation of the given non-container value /// </summary> /// <param name="value">The scalar value of which to get the string representation</param> /// <param name="type">The type as string, e.g int,string,Foo </param> /// <param name="content">The content as string, e.g. 42,"foo",bar } </param> /// <param name="attrType">The attribute type of the value (may be null)</param> /// <param name="graph">The graph with the model and the element names</param> public static void ToString(object value, out string type, out string content, AttributeType attrType, IGraph graph) { if (attrType == null) { ToString(value, out type, out content, graph); return; } Debug.Assert(attrType.Kind != AttributeKind.SetAttr && attrType.Kind != AttributeKind.MapAttr && attrType.Kind != AttributeKind.ArrayAttr && attrType.Kind != AttributeKind.DequeAttr); type = TypesHelper.AttributeTypeToXgrsType(attrType); if (type == "object") { content = ToStringObject(value, attrType, graph); } else { content = ToString(value, attrType, graph); } }
protected override string OutputParameterType(int i, Invocation invocation, GrGenType ownerType) { if (invocation is RuleInvocation) { RuleInvocation ruleInvocation = (RuleInvocation)invocation; IAction action = SequenceBase.GetAction(ruleInvocation); return(TypesHelper.DotNetTypeToXgrsType(action.RulePattern.Outputs[i])); } else if (invocation is SequenceInvocation) { SequenceSequenceCallInterpreted seqInvocation = (SequenceSequenceCallInterpreted)invocation; if (seqInvocation.SequenceDef is SequenceDefinitionInterpreted) { SequenceDefinitionInterpreted seqDef = (SequenceDefinitionInterpreted)seqInvocation.SequenceDef; return(seqDef.OutputVariables[i].Type); } else { SequenceDefinitionCompiled seqDef = (SequenceDefinitionCompiled)seqInvocation.SequenceDef; return(TypesHelper.DotNetTypeToXgrsType(seqDef.SeqInfo.OutParameterTypes[i])); } } else if (invocation is ProcedureInvocation) { ProcedureInvocation procInvocation = (ProcedureInvocation)invocation; if (ownerType != null) { IProcedureDefinition procDef = ownerType.GetProcedureMethod(procInvocation.Name); return(TypesHelper.DotNetTypeToXgrsType(procDef.Outputs[i])); } else { SequenceComputationProcedureCallInterpreted procInvocationInterpreted = (SequenceComputationProcedureCallInterpreted)procInvocation; return(TypesHelper.DotNetTypeToXgrsType(procInvocationInterpreted.ProcedureDef.Outputs[i])); } } throw new Exception("Internal error"); }
public static IList FillArray(IList arrayToCopyTo, string valueTypeName, IList arrayToCopy, IGraphModel model) { NodeType nodeType = TypesHelper.GetNodeType(valueTypeName, model); if (nodeType != null) { FillArrayWithNode(arrayToCopyTo, nodeType, arrayToCopy); } else { EdgeType edgeType = TypesHelper.GetEdgeType(valueTypeName, model); if (edgeType != null) { FillArrayWithEdge(arrayToCopyTo, edgeType, arrayToCopy); } else { Type varType = TypesHelper.GetType(valueTypeName, model); FillArrayWithVar(arrayToCopyTo, varType, arrayToCopy); } } return(arrayToCopyTo); }
public static Dictionary <K, SetValueType> FillSet <K>(Dictionary <K, SetValueType> setToCopyTo, string valueTypeName, IDictionary setToCopy, IGraphModel model) { NodeType nodeType = TypesHelper.GetNodeType(valueTypeName, model); if (nodeType != null) { FillSetWithNode(setToCopyTo, nodeType, setToCopy); } else { EdgeType edgeType = TypesHelper.GetEdgeType(valueTypeName, model); if (edgeType != null) { FillSetWithEdge(setToCopyTo, edgeType, setToCopy); } else { Type varType = TypesHelper.GetType(valueTypeName, model); FillSetWithVar(setToCopyTo, varType, setToCopy); } } return(setToCopyTo); }
public static Dictionary <K, V> FillMap <K, V>(Dictionary <K, V> mapToCopyTo, string keyTypeName, string valueTypeName, IDictionary mapToCopy, IGraphModel model) { NodeType nodeType = TypesHelper.GetNodeType(keyTypeName, model); if (nodeType != null) { FillMapWithKeyNode(mapToCopyTo, nodeType, valueTypeName, mapToCopy, model); } else { EdgeType edgeType = TypesHelper.GetEdgeType(keyTypeName, model); if (edgeType != null) { FillMapWithKeyEdge(mapToCopyTo, edgeType, valueTypeName, mapToCopy, model); } else { Type varType = TypesHelper.GetType(keyTypeName, model); FillMapWithKeyVar(mapToCopyTo, varType, valueTypeName, mapToCopy, model); } } return(mapToCopyTo); }
/// <summary> /// Returns a string representation of the given non-container value /// </summary> /// <param name="value">The scalar value of which to get the string representation</param> /// <param name="type">The type as string, e.g int,string,Foo </param> /// <param name="content">The content as string, e.g. 42,"foo",bar } </param> /// <param name="attrType">The attribute type of the value (may be null)</param> /// <param name="graph">The graph with the model and the element names</param> /// <param name="firstLevelObjectEmitted">Prevents emitting of further objects and thus infinite regressions</param> /// <param name="nameToObject">If not null, the names of visited objects are added</param> /// <param name="procEnv">If not null, the processing environment is used for transient object unique id emitting and fetching</param> public static void ToString(object value, out string type, out string content, AttributeType attrType, IGraph graph, bool firstLevelObjectEmitted, IDictionary <string, IObject> nameToObject, IGraphProcessingEnvironment procEnv) { if (attrType == null) { ToString(value, out type, out content, graph, firstLevelObjectEmitted, nameToObject, procEnv); return; } Debug.Assert(attrType.Kind != AttributeKind.SetAttr && attrType.Kind != AttributeKind.MapAttr && attrType.Kind != AttributeKind.ArrayAttr && attrType.Kind != AttributeKind.DequeAttr); type = TypesHelper.AttributeTypeToXgrsType(attrType); if (type == "object") { content = ToStringObject(value, attrType, graph); } else { content = ToString(value, attrType, graph, firstLevelObjectEmitted, nameToObject, procEnv); } }
public static IDeque FillDeque(IDeque dequeToCopyTo, string valueTypeName, IDeque dequeToCopy, IGraphModel model) { NodeType nodeType = TypesHelper.GetNodeType(valueTypeName, model); if (nodeType != null) { FillDequeWithNode(dequeToCopyTo, nodeType, dequeToCopy); } else { EdgeType edgeType = TypesHelper.GetEdgeType(valueTypeName, model); if (edgeType != null) { FillDequeWithEdge(dequeToCopyTo, edgeType, dequeToCopy); } else { Type varType = TypesHelper.GetType(valueTypeName, model); FillDequeWithVar(dequeToCopyTo, varType, dequeToCopy); } } return(dequeToCopyTo); }
public static IDictionary FillMapWithKeyVar(IDictionary mapToCopyTo, Type keyVarType, string valueTypeName, IDictionary mapToCopy, IGraphModel model) { NodeType nodeType = TypesHelper.GetNodeType(valueTypeName, model); if (nodeType != null) { FillMapWithKeyVarValueNode(mapToCopyTo, keyVarType, nodeType, mapToCopy); } else { EdgeType edgeType = TypesHelper.GetEdgeType(valueTypeName, model); if (edgeType != null) { FillMapWithKeyVarValueEdge(mapToCopyTo, keyVarType, edgeType, mapToCopy); } else { Type valueType = TypesHelper.GetType(valueTypeName, model); FillMapWithKeyVarValueVar(mapToCopyTo, keyVarType, valueType, mapToCopy); } } return(mapToCopyTo); }
public override void Check(SequenceCheckingEnvironment env) { base.Check(env); if(DestVar.Type == "") return; // we can't gain access to an attribute type if the variable is untyped, only runtime-check possible GrGenType nodeOrEdgeType = TypesHelper.GetNodeOrEdgeType(DestVar.Type, env.Model); if(nodeOrEdgeType == null) throw new SequenceParserException(Symbol, "node or edge type", DestVar.Type); AttributeType attributeType = nodeOrEdgeType.GetAttributeType(AttributeName); if(attributeType == null) throw new SequenceParserException(AttributeName, SequenceParserError.UnknownAttribute); string ContainerType = TypesHelper.AttributeTypeToXgrsType(attributeType); if(TypesHelper.ExtractSrc(ContainerType) == null || TypesHelper.ExtractDst(ContainerType) == null || TypesHelper.ExtractDst(ContainerType) == "SetValueType") { throw new SequenceParserException(Symbol, "map<S,T> or array<T> or deque<T>", DestVar.Type); } if(ContainerType.StartsWith("array")) { if(!TypesHelper.IsSameOrSubtype(KeyExpression.Type(env), "int", env.Model)) throw new SequenceParserException(Symbol, "int", KeyExpression.Type(env)); } else if(ContainerType.StartsWith("deque")) { if(!TypesHelper.IsSameOrSubtype(KeyExpression.Type(env), "int", env.Model)) throw new SequenceParserException(Symbol, "int", KeyExpression.Type(env)); } else { if(!TypesHelper.IsSameOrSubtype(KeyExpression.Type(env), TypesHelper.ExtractSrc(ContainerType), env.Model)) throw new SequenceParserException(Symbol, TypesHelper.ExtractSrc(ContainerType), KeyExpression.Type(env)); } }
private static void ToString(object value, out string type, out string content, IGraph graph) { if (value == null) { type = "<INVALID>"; content = ToString(value, null, graph); return; } if (value is IMatch) { type = "IMatch"; content = ToString((IMatch)value, graph); return; } Debug.Assert(value.GetType().Name != "Dictionary`2" && value.GetType().Name != "List`1" && value.GetType().Name != "Deque`1"); type = TypesHelper.DotNetTypeToXgrsType(value.GetType().Name, value.GetType().FullName); foreach (ExternalType externalType in graph.Model.ExternalTypes) { if (externalType.Name == value.GetType().Name) { type = "object"; } } if (type == "object") { content = ToStringObject(value, null, graph); } else { content = ToString(value, null, graph); } }
public override void Check(SequenceCheckingEnvironment env) { base.Check(env); if (DestVar.Type == "") { return; // we can't check source and destination types if the variable is untyped, only runtime-check possible } if (TypesHelper.ExtractSrc(DestVar.Type) == null || TypesHelper.ExtractDst(DestVar.Type) == null || TypesHelper.ExtractDst(DestVar.Type) == "SetValueType") { throw new SequenceParserException(Symbol, "map<S,T> or array<T> or deque<T>", DestVar.Type); } if (DestVar.Type.StartsWith("array")) { if (!TypesHelper.IsSameOrSubtype(KeyExpression.Type(env), "int", env.Model)) { throw new SequenceParserException(Symbol, "int", KeyExpression.Type(env)); } } else if (DestVar.Type.StartsWith("deque")) { if (!TypesHelper.IsSameOrSubtype(KeyExpression.Type(env), "int", env.Model)) { throw new SequenceParserException(Symbol, "int", KeyExpression.Type(env)); } } else { if (!TypesHelper.IsSameOrSubtype(KeyExpression.Type(env), TypesHelper.ExtractSrc(DestVar.Type), env.Model)) { throw new SequenceParserException(Symbol, TypesHelper.ExtractSrc(DestVar.Type), KeyExpression.Type(env)); } } }
/// <summary> /// Helper for checking procedure method calls. /// Checks whether called entity exists, type checks the input, type checks the output. /// Throws an exception when an error is found. /// </summary> /// <param name="seqCompProcMethodCall">The procedure method call to check</param> /// <param name="targetVar">The target of the procedure method call</param> public void CheckProcedureMethodCall(SequenceVariable targetVar, SequenceComputationProcedureMethodCall seqCompProcMethodCall) { if (targetVar.Type == "") { // only runtime checks possible (we could check whether the called procedure signature exists in at least one of the model types, if not it's a type error, can't work at runtime, but that kind of negative check is not worth the effort) return; } GrGenType ownerType = TypesHelper.GetNodeOrEdgeType(targetVar.Type, Model); if (ownerType == null) { // error, must be node or edge type throw new SequenceParserException(targetVar.Type, SequenceParserError.UserMethodsOnlyAvailableForGraphElements); } // check whether called procedure method exists if (ownerType.GetProcedureMethod(seqCompProcMethodCall.Name) == null) { throw new SequenceParserException(seqCompProcMethodCall, -1, SequenceParserError.UnknownProcedure); } CheckProcedureCallBase(seqCompProcMethodCall, ownerType); }
/// <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); } } }
/// <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); } } }
public static IList Extract(object container, string memberOrAttribute, IGraphProcessingEnvironment procEnv) { IList array = (IList)container; string arrayType = TypesHelper.DotNetTypeToXgrsType(array.GetType()); string arrayValueType = TypesHelper.ExtractSrc(arrayType); if (arrayValueType.StartsWith("match<")) { if (arrayValueType == "match<>") { if (array.Count > 0) { IMatch match = (IMatch)array[0]; object matchElement = match.GetMember(memberOrAttribute); Type matchElementType; if (matchElement is IGraphElement) { matchElementType = TypesHelper.GetType(((IGraphElement)matchElement).Type, procEnv.Graph.Model); } else { matchElementType = matchElement.GetType(); } Type listType = typeof(List <>).MakeGenericType(matchElementType); IList extractedArray = (IList)Activator.CreateInstance(listType); ExtractMatchMember(array, memberOrAttribute, extractedArray); return(extractedArray); } else { return(new List <object>()); } } else { if (arrayValueType.StartsWith("match<class ")) { MatchClassFilterer matchClass = procEnv.Actions.GetMatchClass(TypesHelper.GetMatchClassName(arrayValueType)); IPatternElement element = matchClass.info.GetPatternElement(memberOrAttribute); GrGenType elementType = element.Type; Type listType = typeof(List <>).MakeGenericType(TypesHelper.GetType(elementType, procEnv.Graph.Model)); IList extractedArray = (IList)Activator.CreateInstance(listType); ExtractMatchMember(array, memberOrAttribute, extractedArray); return(extractedArray); } else { IAction action = procEnv.Actions.GetAction(TypesHelper.GetRuleName(arrayValueType)); IPatternElement element = action.RulePattern.PatternGraph.GetPatternElement(memberOrAttribute); GrGenType elementType = element.Type; Type listType = typeof(List <>).MakeGenericType(TypesHelper.GetType(elementType, procEnv.Graph.Model)); IList extractedArray = (IList)Activator.CreateInstance(listType); ExtractMatchMember(array, memberOrAttribute, extractedArray); return(extractedArray); } } } else { GrGenType graphElementType = TypesHelper.GetNodeOrEdgeType(arrayValueType, procEnv.Graph.Model); if (graphElementType != null) { AttributeType attributeType = graphElementType.GetAttributeType(memberOrAttribute); Type listType = typeof(List <>).MakeGenericType(attributeType.Type); IList extractedArray = (IList)Activator.CreateInstance(listType); ExtractAttribute(array, memberOrAttribute, extractedArray); return(extractedArray); } else { if (array.Count > 0) { IGraphElement graphElement = (IGraphElement)array[0]; object element = graphElement.GetAttribute(memberOrAttribute); Type elementType; if (element is IGraphElement) { elementType = TypesHelper.GetType(((IGraphElement)element).Type, procEnv.Graph.Model); } else { elementType = element.GetType(); } Type listType = typeof(List <>).MakeGenericType(elementType); IList extractedArray = (IList)Activator.CreateInstance(listType); ExtractAttribute(array, memberOrAttribute, extractedArray); return(extractedArray); } else { return(new List <object>()); } } } }