protected override Expression VisitMember(MemberExpression node) { Expression newNode = null; if (evaluator.EnsureKnownType( node.Member, replaceCompilerGeneratedType: _ => { newNode = evaluator.EvaluateCompilerGenerated(node, protocol) ?? CompilerGenerated.Get( Visit(node.Expression), node.Member, type => { evaluator.EnsureKnownType( type, replaceCompilerGeneratedType: __ => type = typeof(CompilerGenerated), genericArgumentsUpdated: updatedType => type = updatedType); return(type); }); }, unknownType: (_, __) => newNode = evaluator.GetValue(node, this, protocol))) { return(newNode); } else { return(base.VisitMember(node)); } }
protected override Expression VisitNew(NewExpression node) { NewExpression newNode = null; if (evaluator.EnsureKnownType( node.Constructor, replaceCompilerGeneratedType: _ => newNode = CompilerGenerated.New(node.Members, Visit(node.Arguments)), genericArgumentsUpdated: updatedType => { /* Overload resolution should be unaffected here, so keep the same constructor index. We're just swapping a * compiler-generated type for the internal CompilerGenerated class, neither of which can be statically * referenced by users. */ var flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; var oldConstructorIndex = Array.IndexOf(node.Constructor.DeclaringType.GetConstructors(flags), node.Constructor); var newConstructor = updatedType.GetConstructors(flags)[oldConstructorIndex]; newNode = Expression.New(newConstructor, Visit(node.Arguments), node.Members); })) { return(newNode); } return(base.VisitNew(node)); }
protected override Expression VisitBinary(BinaryExpression node) { if (node.NodeType == ExpressionType.Assign) { MethodCallExpression newNode = null; if (evaluator.EnsureKnownType( node.Left.Type, replaceCompilerGeneratedType: _ => newNode = CompilerGenerated.Set(Visit(node.Left), Visit(node.Right)))) { return(newNode); } } return(base.VisitBinary(node)); }