private void ProcessExpression([NotNull] GraphDataFlowExpressionNode node, [NotNull] GraphNode[] path) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (path == null) { throw new ArgumentNullException(nameof(path)); } var implemented = false; switch (node.Expression) { case AssignmentBase assignmentBase: ProcessAssignment(node, assignmentBase, path); implemented = true; break; case FunctionCallOperator functionCallOperator: break; default: throw new ArgumentOutOfRangeException(nameof(node.Expression)); } if (!implemented) { Log.Information("Expression: {Expression}", node.Expression); } }
public void Convert() { MethodRoot.Start = ConvertNode(MethodRoot.Start); var graphNodes = MethodRoot.Start.IterateGraphNodesRecursive(false).ToArray(); foreach (var graphNode in graphNodes) { ConvertNode(graphNode); } GraphNode ConvertNode(GraphNode graphNode) { return(graphNode switch { null => throw new ArgumentOutOfRangeException(nameof(graphNode)), GraphDataFlowBlockNode _ => graphNode, GraphDataFlowExpressionNode _ => graphNode, GraphControlFlowBlockNode blockNode => ConvertControlFlowNode(blockNode), GraphControlFlowConditionalNode conditionalNode => ConvertControlFlowNode(conditionalNode), GraphControlFlowReturnNode returnNode => ConvertControlFlowNode(returnNode), GraphDataFlowConditionalNode _ => graphNode, GraphDataFlowReturnNode _ => graphNode, _ => throw new ArgumentOutOfRangeException(nameof(graphNode)) }); }
private void ProcessAssignment( [NotNull] GraphDataFlowExpressionNode node, [NotNull] AssignmentBase assignmentBase, [NotNull] GraphNode[] path) { IValue left = assignmentBase.Left; var right = assignmentBase.Right; left = node.EnterAnalysisContext[left]; if (left == null) { Log.Warning("Skipping {Assignment} since LHS expression resolved to null", assignmentBase); return; } var leftVariant = left is ValueVariantBase leftOldVariableVariant ? leftOldVariableVariant : throw new ArgumentOutOfRangeException(nameof(left)); leftVariant = leftVariant.Clone(node.EnterAnalysisContext, path); var implemented = false; switch (assignmentBase) { case OperatorAssignment operatorAssignment: { var @operator = operatorAssignment.Operator; switch (@operator) { case BinaryPureBase binaryPureBase: { var interval = binaryPureBase.ApplyPossibleVariants(leftVariant, right); if (interval != null) { leftVariant.Value = new DataValueInterval(interval, leftVariant.Value.Constraints); implemented = true; } break; } case UnaryPureBase unaryPureBase: goto default; default: throw new ArgumentOutOfRangeException(nameof(@operator)); } break; } case SimpleAssignment _: { var interval = node.EnterAnalysisContext.ResolveToRange(right); if (interval != null) { leftVariant.Value = new DataValueInterval(interval, Array.Empty <LogicExpressionBase>()); implemented = true; } break; } default: throw new ArgumentOutOfRangeException(nameof(assignmentBase)); } if (!implemented) { Log.Information("Assignment: ({LeftKind}) {Operator} ({RightKind})", left.GetType().Name, assignmentBase, right?.GetType().Name); return; } node.ExitAnalysisContext[leftVariant] = leftVariant; }