Ejemplo n.º 1
0
        public override BoundNode VisitCall(BoundCall node)
        {
            var rewrittenMethodSymbol = VisitMethodSymbol(node.Method);
            var rewrittenReceiver     = (BoundExpression)this.Visit(node.ReceiverOpt);
            var rewrittenArguments    = (ImmutableArray <BoundExpression>) this.VisitList(node.Arguments);
            var rewrittenType         = this.VisitType(node.Type);

            Debug.Assert(rewrittenMethodSymbol.IsMetadataVirtual() == node.Method.IsMetadataVirtual());

            // If the original receiver was a base access and it was rewritten,
            // change the method to point to the wrapper method
            if (BaseReferenceInReceiverWasRewritten(node.ReceiverOpt, rewrittenReceiver) && node.Method.IsMetadataVirtual())
            {
                rewrittenMethodSymbol = GetMethodWrapperForBaseNonVirtualCall(rewrittenMethodSymbol, node.Syntax);
            }

            return(node.Update(
                       rewrittenReceiver,
                       rewrittenMethodSymbol,
                       rewrittenArguments,
                       node.ArgumentNamesOpt,
                       node.ArgumentRefKindsOpt,
                       node.IsDelegateCall,
                       node.Expanded,
                       node.InvokedAsExtensionMethod,
                       node.ArgsToParamsOpt,
                       node.ResultKind,
                       node.BinderOpt,
                       rewrittenType));
        }
Ejemplo n.º 2
0
        public override BoundNode VisitCall(BoundCall node)
        {
            var receiver = node.ReceiverOpt;

            // matches or a bit stronger than EmitReceiverRef
            // if there are any doubts that receiver is a ref type, 
            // assume we will need an address (that will prevent scheduling of receiver).
            if (!node.Method.IsStatic)
            {
                receiver = VisitCallReceiver(receiver);
            }
            else
            {
                // TODO: for some reason receiver could be not null even if method is static...
                //       it seems wrong, ignore for now.
                _counter += 1;
                receiver = null;
            }

            MethodSymbol method = node.Method;
            var rewrittenArguments = VisitArguments(node.Arguments, method.Parameters);

            return node.Update(receiver, method, rewrittenArguments);
        }
Ejemplo n.º 3
0
        public override BoundNode VisitCall(BoundCall node)
        {
            var rewrittenMethodSymbol = VisitMethodSymbol(node.Method);
            var rewrittenReceiver = (BoundExpression)this.Visit(node.ReceiverOpt);
            var rewrittenArguments = (ImmutableArray<BoundExpression>)this.VisitList(node.Arguments);
            var rewrittenType = this.VisitType(node.Type);

            Debug.Assert(rewrittenMethodSymbol.IsMetadataVirtual() == node.Method.IsMetadataVirtual());

            // If the original receiver was a base access and it was rewritten, 
            // change the method to point to the wrapper method
            if (BaseReferenceInReceiverWasRewritten(node.ReceiverOpt, rewrittenReceiver) && node.Method.IsMetadataVirtual())
            {
                rewrittenMethodSymbol = GetMethodWrapperForBaseNonVirtualCall(rewrittenMethodSymbol, node.Syntax);
            }

            return node.Update(
                rewrittenReceiver,
                rewrittenMethodSymbol,
                rewrittenArguments,
                node.ArgumentNamesOpt,
                node.ArgumentRefKindsOpt,
                node.IsDelegateCall,
                node.Expanded,
                node.InvokedAsExtensionMethod,
                node.ArgsToParamsOpt,
                node.ResultKind,
                rewrittenType);
        }
Ejemplo n.º 4
0
        public override BoundNode VisitCall(BoundCall node)
        {
            Debug.Assert(node != null);

            // Avoid rewriting if node has errors since one or more
            // of the arguments may not be the correct rvalue/lvalue.
            if (node.HasErrors)
            {
                return(node);
            }

            // Start by rewriting the arguments and receiver:
            var rewrittenReceiver  = (BoundExpression)Visit(node.ReceiverOpt);
            var rewrittenArguments = VisitList(node.Arguments);
            var method             = node.Method;

            // If the mapping from arguments to parameters is perfectly in order, no complex rewriting is needed.
            if (node.ArgsToParamsOpt.IsNull && !node.Expanded)
            {
                return(node.Update(rewrittenReceiver, method, rewrittenArguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.Expanded, node.ArgsToParamsOpt, node.Type));
            }

            var argumentRefKinds = node.ArgumentRefKindsOpt;
            ReadOnlyArray <LocalSymbol> temps;

            RewriteArguments(method,
                             node.Expanded,
                             node.ArgsToParamsOpt,
                             ref argumentRefKinds,
                             ref rewrittenArguments,
                             out temps);

            var delegateNode = node as BoundDelegateCall;

            if (temps.IsNullOrEmpty)
            {
                return((delegateNode != null)
                    ? delegateNode.Update(
                           rewrittenReceiver,
                           method,
                           rewrittenArguments,
                           ReadOnlyArray <string> .Null,
                           argumentRefKinds,
                           false,
                           ReadOnlyArray <int> .Null,
                           node.Type)
                    : node.Update(
                           rewrittenReceiver,
                           method,
                           rewrittenArguments,
                           ReadOnlyArray <string> .Null,
                           argumentRefKinds,
                           false,
                           ReadOnlyArray <int> .Null,
                           node.Type));
            }
            else
            {
                return(new BoundSequence(
                           null,
                           null,
                           temps,
                           ReadOnlyArray <BoundExpression> .Empty,
                           (delegateNode != null)
                        ? new BoundDelegateCall(
                               node.Syntax,
                               node.SyntaxTree,
                               rewrittenReceiver,
                               method,
                               rewrittenArguments,
                               ReadOnlyArray <string> .Null,
                               argumentRefKinds,
                               false,
                               ReadOnlyArray <int> .Null,
                               node.Type)
                        : new BoundCall(
                               node.Syntax,
                               node.SyntaxTree,
                               rewrittenReceiver,
                               method,
                               rewrittenArguments,
                               ReadOnlyArray <string> .Null,
                               argumentRefKinds,
                               false,
                               ReadOnlyArray <int> .Null,
                               node.Type),
                           node.Type
                           ));
            }
        }
        public override BoundNode VisitCall(BoundCall node)
        {
            var receiver = node.ReceiverOpt;

            // matches or a bit stronger than EmitReceiverRef
            // if there are any doubts that receiver is a ref type, 
            // assume we will need an address (that will prevent scheduling of receiver).
            if (!node.Method.IsStatic)
            {
                var receiverType = receiver.Type;
                ExprContext context;

                if (receiverType.IsReferenceType)
                {
                    if (receiverType.IsTypeParameter())
                    {
                        // type param receiver that we statically know is a reference will be boxed
                        context = ExprContext.Box;
                    }
                    else
                    {
                        // reference receivers will be used as values
                        context = ExprContext.Value;
                    }
                }
                else
                {
                    // everything else will get an address taken
                    context = ExprContext.Address;
                }

                receiver = VisitExpression(receiver, context);
            }
            else
            {
                // TODO: for some reason receiver could be not null even if method is static...
                //       it seems wrong, ignore for now.
                this.counter += 1;
                receiver = null;
            }

            MethodSymbol method = node.Method;
            var rewrittenArguments = VisitArguments(node.Arguments, method.Parameters);

            return node.Update(receiver, method, rewrittenArguments);
        }
        public override BoundNode VisitCall(BoundCall node)
        {
            Debug.Assert(node != null);

            // Avoid rewriting if node has errors since one or more
            // of the arguments may not be the correct rvalue/lvalue.
            if (node.HasErrors)
            {
                return node;
            }

            // Start by rewriting the arguments and receiver:
            var rewrittenReceiver = (BoundExpression)Visit(node.ReceiverOpt);
            var rewrittenArguments = VisitList(node.Arguments);
            var method = node.Method;

            // If the mapping from arguments to parameters is perfectly in order, no complex rewriting is needed.
            if (node.ArgsToParamsOpt.IsNull && !node.Expanded)
            {
                return node.Update(rewrittenReceiver, method, rewrittenArguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.Expanded, node.ArgsToParamsOpt, node.Type);
            }

            var argumentRefKinds = node.ArgumentRefKindsOpt;
            ReadOnlyArray<LocalSymbol> temps;

            RewriteArguments(method,
                        node.Expanded,
                        node.ArgsToParamsOpt,
                        ref argumentRefKinds,
                        ref rewrittenArguments,
                        out temps);

            var delegateNode = node as BoundDelegateCall;
            if (temps.IsNullOrEmpty)
            {
                return (delegateNode != null)
                    ? delegateNode.Update(
                        rewrittenReceiver,
                        method,
                        rewrittenArguments,
                        ReadOnlyArray<string>.Null,
                        argumentRefKinds,
                        false,
                        ReadOnlyArray<int>.Null,
                        node.Type)
                    : node.Update(
                        rewrittenReceiver,
                        method,
                        rewrittenArguments,
                        ReadOnlyArray<string>.Null,
                        argumentRefKinds,
                        false,
                        ReadOnlyArray<int>.Null,
                        node.Type);
            }
            else
            {
                return new BoundSequence(
                    null,
                    null,
                    temps,
                    ReadOnlyArray<BoundExpression>.Empty,
                    (delegateNode != null)
                        ? new BoundDelegateCall(
                            node.Syntax,
                            node.SyntaxTree,
                            rewrittenReceiver,
                            method,
                            rewrittenArguments,
                            ReadOnlyArray<string>.Null,
                            argumentRefKinds,
                            false,
                            ReadOnlyArray<int>.Null,
                            node.Type)
                        : new BoundCall(
                            node.Syntax,
                            node.SyntaxTree,
                            rewrittenReceiver,
                            method,
                            rewrittenArguments,
                            ReadOnlyArray<string>.Null,
                            argumentRefKinds,
                            false,
                            ReadOnlyArray<int>.Null,
                            node.Type),
                    node.Type
                );
            }
        }