private static bool CanInline(Expression context, ParameterExpression parameter, Expression expression) { var fvs = FreeVariableScanner.Scan(expression).AsCollection(); if (fvs.Count > 0) { var ca = new CaptureAnalyzer(parameter, fvs); ca.Visit(context); return(!ca.HasCapture); } return(true); }
/// <summary> /// Throws an unbound parameter exception if the specified expression contains unbound parameters. /// </summary> /// <param name="expression">Expression to check for unbound parameters.</param> /// <param name="message">Exception message to use for signaling unbound parameters.</param> public static void ThrowIfOpen(Expression expression, string message) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var variables = FreeVariableScanner.Scan(expression); if (variables.Any()) { throw new UnboundParameterException(message, expression, variables); } }
/// <summary> /// Evaluates the specified expression. /// </summary> /// <param name="expression">Expression to evaluate.</param> /// <returns>Expression containing the evaluation result.</returns> protected virtual Expression Evaluate(Expression expression) { // NOTE: Scope analysis could be improved by tracking use sites of variables on a lookaside stack. // However, in typical usage patterns the number of subtrees that can be partially evaluated // is expected to be low, so the number of times free variables have to be scanned is going // to be relatively small. if (expression != null && expression.NodeType != ExpressionType.Constant && !FreeVariableScanner.HasFreeVariables(expression)) { return(EvaluateCore(expression)); } return(expression); }