public static Expression WalkGraph(Expression op, IGraphInspector inspector) { // The pre walk call op = inspector.OnBeforeWalk(op); ExpressionType type = op.Type; switch (type) { case ExpressionType.Function: InspectParamList(inspector, op, "param_count", "arg"); break; case ExpressionType.Select: InspectParam(inspector, op, "join"); InspectParam(inspector, op, "filter"); InspectParam(inspector, op, "havingfilter"); InspectParamList(inspector, op, "out_count", "out"); InspectParamList(inspector, op, "groupby_count", "groupby"); InspectParamList(inspector, op, "orderby_count", "orderby"); break; case ExpressionType.Join: InspectParam(inspector, op, "left"); InspectParam(inspector, op, "right"); InspectParam(inspector, op, "filter"); break; // Single passthrough case ExpressionType.AliasTableName: case ExpressionType.AliasVariableName: InspectParam(inspector, op, "child"); break; case ExpressionType.Filter: InspectParam(inspector, op, "child"); InspectParam(inspector, op, "filter"); break; // Terminators case ExpressionType.FetchVariable: case ExpressionType.FetchStatic: case ExpressionType.FetchParameter: case ExpressionType.FetchGlob: case ExpressionType.FetchTable: break; default: throw new ArgumentException("Unknown operation " + op.Type); } // The post expression call op = inspector.OnAfterWalk(op); // Return the operation return op; }
private static void InspectParamList(IGraphInspector inspector, Expression op, string size_arg, string pre_arg) { int sz = (int)op.GetArgument(size_arg); for (int i = 0; i < sz; ++i) { InspectParam(inspector, op, pre_arg + i); } }
private static void InspectParam(IGraphInspector inspector, Expression expression, string paramArg) { object paramVal = expression.GetArgument(paramArg); if (paramVal != null && paramVal is Expression) { Expression inspected = paramVal as Expression; expression.SetArgument(paramArg, WalkGraph(inspected, inspector)); } }