protected override Expression VisitNew(NewExpression node, Type expectedType) { NewExpression newNode = null; if (evaluator.EnsureKnownType( node.Constructor, replaceCompilerGeneratedType: _ => newNode = CompilerGenerated.New(node.Members, Visit(node.Arguments, null)), 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, null), node.Members); })) { return(newNode); } return(base.VisitNew(node, expectedType)); }
protected override Expression VisitMember(MemberExpression node, Type expectedType) { Expression newNode = null; if (evaluator.EnsureKnownType( node.Member, replaceCompilerGeneratedType: _ => { newNode = evaluator.EvaluateCompilerGenerated(node, expectedType, protocol) ?? CompilerGenerated.Get( Visit(node.Expression, (node.Member as FieldInfo)?.FieldType ?? (node.Member as PropertyInfo)?.PropertyType), 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, expectedType)); } }
protected override Expression VisitBinary(BinaryExpression node, Type expectedType) { if (node.NodeType == ExpressionType.Assign) { MethodCallExpression newNode = null; if (evaluator.EnsureKnownType( node.Left.Type, replaceCompilerGeneratedType: _ => newNode = CompilerGenerated.Set(Visit(node.Left, node.Method.GetParameters()[0].ParameterType), Visit(node.Right, node.Method.GetParameters()[1].ParameterType)))) { return(newNode); } } return(base.VisitBinary(node, expectedType)); }