public void UpdateDoesntRepeatEnumeration(int blockSize) { ConstantExpression constant = Expression.Constant(0); IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray(); BlockExpression block = Expression.Block(expressions); Assert.Same(block, block.Update(null, new RunOnceEnumerable <Expression>(expressions))); Assert.NotSame( block, block.Update(null, new RunOnceEnumerable <Expression>(PadBlock(blockSize - 1, Expression.Constant(1))))); }
public void UpdateDoesntRepeatEnumeration(int blockSize) { ConstantExpression constant = Expression.Constant(0); IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray(); ParameterExpression[] vars = { Expression.Variable(typeof(int)), Expression.Variable(typeof(string)) }; BlockExpression block = Expression.Block(vars, expressions); Assert.Same(block, block.Update(new RunOnceEnumerable <ParameterExpression>(vars), block.Expressions)); vars = new[] { Expression.Variable(typeof(int)), Expression.Variable(typeof(string)) }; Assert.NotSame(block, block.Update(new RunOnceEnumerable <ParameterExpression>(vars), block.Expressions)); }
private BlockExpression AddIncludes(BlockExpression shaperBlock) { if (_pendingIncludes.Count == 0) { return(shaperBlock); } var shaperExpressions = new List <Expression>(shaperBlock.Expressions); var instanceVariable = shaperExpressions[shaperExpressions.Count - 1]; shaperExpressions.RemoveAt(shaperExpressions.Count - 1); var includesToProcess = _pendingIncludes; _pendingIncludes = new List <IncludeExpression>(); foreach (var include in includesToProcess) { AddInclude(shaperExpressions, include, shaperBlock, instanceVariable); } shaperExpressions.Add(instanceVariable); shaperBlock = shaperBlock.Update(shaperBlock.Variables, shaperExpressions); return(shaperBlock); }
protected override Expression VisitBlock(BlockExpression node) { var variables = VisitAndConvert(node.Variables, nameof(VisitBlock)); var expressions = Visit(node.Expressions); return(node.Update(variables, expressions)); }
/// <summary> /// Visit block expressions for scope tracking and closure emitting purposes. /// </summary> /// <param name="node">The block expression to rewrite.</param> /// <returns>The rewritten expression.</returns> protected override Expression VisitBlock(BlockExpression node) { // // Introduce a new scope and keep track of the original scope in order to restore // it after visiting child expressions. // var currentScope = _scope; try { var scope = _analysis[node]; _scope = new CompilerScope(currentScope, scope); if (!scope.HasHoistedLocals) { // // In case there are no hoisted locals, we don't need to use a builder to // instantiate a closure. Simply visit the child expressions and update. // var expressions = Visit(node.Expressions); return(node.Update(node.Variables, expressions)); } else { // // In case there are hoisted locals, enter the scope to obtain a builder, // append the visited child expressions, and return a new block. This will // add the statements needed to instantiate the closure and link it to its // parent (if any). // var expressions = node.Expressions; var n = expressions.Count; // // Note we don't copy hoisted locals during Enter because the storage // location of these is superseded by the storage field in the closure. // var builder = _scope.Enter(count: n, copyLocals: false); for (var i = 0; i < n; i++) { builder.Append(Visit(expressions[i])); } // // Note that we don't update the original block here; the builder will // create a new block anyway, and we can simply use that as our substitute, // provided the original (non-hoisted) locals are declared. // return(builder.Finish(declareLocals: true)); } } finally { _scope = currentScope; } }
public void UpdateWithExpressionsReturnsSame(object value, int blockSize) { ConstantExpression constant = Expression.Constant(value, value.GetType()); IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant); BlockExpression block = Expression.Block(SingleParameter, expressions); Assert.Same(block, block.Update(block.Variables, block.Expressions)); }
public void UpdateToNullArguments(int blockSize) { ConstantExpression constant = Expression.Constant(0); IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant); BlockExpression block = Expression.Block(expressions); AssertExtensions.Throws <ArgumentNullException>("expressions", () => block.Update(null, null)); }
public void UpdateDifferentSizeReturnsDifferent(int blockSize) { ConstantExpression constant = Expression.Constant(0); IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray(); BlockExpression block = Expression.Block(expressions); Assert.NotSame(block, block.Update(null, block.Expressions.Prepend(Expression.Empty()))); }
private static BlockExpression Update(BlockExpression node) { // Tests the call of Update to Expression.Block factories. BlockExpression res = node.Update(node.Variables, node.Expressions.ToArray()); Assert.Same(node, res); return(res); }
BlockExpression VisitBlockExpression(BlockExpression node) { return(VisitBlock(() => { VisitBlockVariables(node); var expressions = VisitBlockExpressions(node); return node.Update(node.Variables, expressions); })); }
public void UpdateDifferentSizeReturnsDifferent(int blockSize) { ConstantExpression constant = Expression.Constant(0); IEnumerable <Expression> expressions = PadBlock(blockSize - 1, constant).ToArray(); ParameterExpression[] vars = { Expression.Variable(typeof(int)), Expression.Variable(typeof(string)) }; BlockExpression block = Expression.Block(vars, expressions); Assert.NotSame(block, block.Update(vars, block.Expressions.Prepend(Expression.Empty()))); }
protected override Expression VisitBlock(BlockExpression node) { var variables = node.Variables; if (variables.Count > 0) { var newVariables = Push(variables); var expressions = Visit(node.Expressions); Pop(); return(node.Update(newVariables, expressions)); } else { var expressions = Visit(node.Expressions); return(node.Update(variables, expressions)); } }
protected override Expression VisitBlock(BlockExpression node) { if (CanOptimize(node)) { return(FlattenBlocks(node)); } var variables = VisitAndConvert(node.Variables, nameof(VisitBlock)); var expressions = VisitSequence(node.Expressions); return(node.Update(variables, expressions)); }
/// <summary> /// Visits a block expression. During the call, the block's variables are mapped in the tracked scope symbol table. /// </summary> /// <param name="node">Block expression to visit.</param> /// <returns>Result of visiting the block expression.</returns> protected virtual Expression VisitBlockCore(BlockExpression node) { if (node == null) { return(null); } var variables = VisitAndConvert(node.Variables, nameof(VisitBlockCore)); var expressions = Visit(node.Expressions); return(node.Update(variables, expressions)); }
/// <inheritdoc /> protected override Expression VisitBlock(BlockExpression node) { if (TryFindAddToCollectionExpression(node.Expressions, out MethodCallExpression methodCallExpression)) { Expression callReplaceDenormalizedInstances = Expression.Call( null, RemoveDenormalizedInstancesMethodInfo, methodCallExpression.Arguments); IList <Expression> newBlockExpressions = new List <Expression>(node.Expressions); newBlockExpressions.Add(callReplaceDenormalizedInstances); node = node.Update(node.Variables, newBlockExpressions); } return(base.VisitBlock(node)); }
// async method cannot have block expression with type not equal to void protected override Expression VisitBlock(BlockExpression node) { if (node.Type == typeof(void)) { Statement.Rewrite(ref node); node.Variables.ForEach(variable => Variables.Add(variable, null)); node = node.Update(Empty <ParameterExpression>(), node.Expressions); return(context.Rewrite(node, base.VisitBlock)); } else { return(VisitBlock(Expression.Block(typeof(void), node.Variables, node.Expressions))); } }
public void UpdateAnyExpressionDifferentReturnsDifferent(int blockSize) { ConstantExpression constant = Expression.Constant(0); Expression[] expressions = PadBlock(blockSize - 1, constant).ToArray(); BlockExpression block = Expression.Block(expressions); for (int i = 0; i != expressions.Length; ++i) { Expression[] newExps = new Expression[expressions.Length]; expressions.CopyTo(newExps, 0); newExps[i] = Expression.Constant(1); Assert.NotSame(block, block.Update(null, newExps)); } }
protected override Expression VisitBlock(BlockExpression node) { var peek = localParameters.Peek(); var variables = node.Variables.Where(variable => !parsedLambda.ParsedParameters.ContainsKey(variable) && !peek.Contains(variable)).ToArray(); foreach (var variable in variables) { peek.Add(variable); } var expressions = node.Expressions.Select(Visit); foreach (var variable in variables) { peek.Remove(variable); } return(node.Update(variables, expressions)); }
protected override Expression VisitBlock(BlockExpression node) { var replacements = default(Dictionary <ParameterExpression, ReplacementInfo>); foreach (var variable in node.Variables) { var type = variable.Type; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(RefHolder <>)) { replacements ??= new Dictionary <ParameterExpression, ReplacementInfo>(); replacements.Add(variable, new ReplacementInfo()); } } if (replacements != null) { _refLocalHolders.Push(replacements); var expressions = Visit(node.Expressions); var updatedReplacements = _refLocalHolders.Pop(); Debug.Assert(updatedReplacements == replacements); var variables = new List <ParameterExpression>(); foreach (var variable in node.Variables) { if (updatedReplacements.TryGetValue(variable, out var replacement)) { variables.AddRange(replacement.Temps); } else { variables.Add(variable); } } return(node.Update(variables, expressions)); } return(base.VisitBlock(node)); }
public T?Simplify <T>(T?expression) where T : Expression { if (expression is null) { return(null); } Expression expr = expression.Reduce() switch { UnaryExpression unaryExpr => unaryExpr.Update(Simplify(unaryExpr.Operand)), BinaryExpression binaryExpr => binaryExpr.Update(Simplify(binaryExpr.Left), binaryExpr.Conversion, Simplify(binaryExpr.Right)), LambdaExpression lambdaExpr => Expression.Lambda(Simplify(lambdaExpr.Body), lambdaExpr.Name, lambdaExpr.TailCall, Simplify(lambdaExpr.Parameters)), TryExpression tryExpr => tryExpr.Update(Simplify(tryExpr.Body), Simplify(tryExpr.Handlers), Simplify(tryExpr.Finally), Simplify(tryExpr.Fault)), NewExpression newExpr => newExpr.Update(Simplify(newExpr.Arguments)), GotoExpression gotoExpr => gotoExpr.Update(gotoExpr.Target, Simplify(gotoExpr.Value)), LoopExpression loopExpr => loopExpr.Update(loopExpr.BreakLabel, loopExpr.ContinueLabel, Simplify(loopExpr.Body)), BlockExpression blockExpr => blockExpr.Update(Simplify(blockExpr.Variables), Simplify(blockExpr.Expressions)), IndexExpression indexExpr => indexExpr.Update(Simplify(indexExpr.Object) !, Simplify(indexExpr.Arguments)), LabelExpression labelExpr => labelExpr.Update(labelExpr.Target, Simplify(labelExpr.DefaultValue)), MemberExpression memberExpr => memberExpr.Update(Simplify(memberExpr.Expression)), SwitchExpression switchExpr => switchExpr.Update(Simplify(switchExpr.SwitchValue), Simplify(switchExpr.Cases), Simplify(switchExpr.DefaultBody)), DynamicExpression dynamicExpr => dynamicExpr.Update(Simplify(dynamicExpr.Arguments)), ListInitExpression listInitExpr => listInitExpr.Update(Simplify(listInitExpr.NewExpression), Simplify(listInitExpr.Initializers)), NewArrayExpression newArrayExpr => newArrayExpr.Update(Simplify(newArrayExpr.Expressions)), InvocationExpression invokeExpr => invokeExpr.Update(Simplify(invokeExpr.Expression), Simplify(invokeExpr.Arguments)), MemberInitExpression memberInitExpr => memberInitExpr.Update(Simplify(memberInitExpr.NewExpression), memberInitExpr.Bindings), MethodCallExpression methodCallExpr => methodCallExpr.Update(Simplify(methodCallExpr.Object), Simplify(methodCallExpr.Arguments)), TypeBinaryExpression typeBinaryExpr => typeBinaryExpr.Update(Simplify(typeBinaryExpr.Expression)), ConditionalExpression condExpr => condExpr.Update(Simplify(condExpr.Test), Simplify(condExpr.IfTrue), Simplify(condExpr.IfFalse)), RuntimeVariablesExpression runtimeVarExpr => runtimeVarExpr.Update(Simplify(runtimeVarExpr.Variables)), _ => expression }; foreach (var transform in transformers) { expr = transform.Transform(expr, this); } return((T)expr); }
BlockExpression Convert(BlockExpression expr) { return(expr.Update(Process(expr.Variables), Process(expr.Expressions))); }
protected override Expression VisitBlock(BlockExpression node) { var variables = VisitAndConvert(node.Variables, nameof(VisitBlock)); var expressions = Visit(node.Expressions); return node.Update(variables, expressions); }
protected override Expression VisitBlock(BlockExpression node) { var exprs = node.Expressions.SelectMany(e => new Expression[] { _log(Expression.Constant("S" + _n++)), Visit(e) }).ToList(); return(node.Update(node.Variables, exprs)); }
protected override Expression VisitBlock(BlockExpression node) { var exprs = node.Expressions.SelectMany(e => new Expression[] { _log(Expression.Constant("S" + _n++)), Visit(e) }).ToList(); return node.Update(node.Variables, exprs); }
protected override Expression VisitBlock(BlockExpression node) { return(node.Update(node.Variables, Visit(node.Expressions))); }
private static BlockExpression Update(BlockExpression node) { // Tests the call of Update to Expression.Block factories. var res = node.Update(node.Variables, node.Expressions.ToArray()); Assert.NotSame(node, res); return res; }
private static BlockExpression SetChildren(ReadOnlySpan <Expression> newChildren, BlockExpression b) => b.Update(b.Variables, newChildren.ToArray());