public override BoundNode?VisitDynamicInvocation(BoundDynamicInvocation node)
                {
                    // perhaps we are passing a variable by ref and mutating it that way
                    if (!node.ArgumentRefKindsOpt.IsDefault)
                    {
                        _mightAssignSomething = true;
                    }
                    else
                    {
                        base.VisitDynamicInvocation(node);
                    }

                    return(null);
                }
Example #2
0
        public override BoundNode VisitDynamicInvocation(BoundDynamicInvocation node)
        {
            if (_inExpressionLambda)
            {
                Error(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, node);

                // avoid reporting errors for the method group:
                if (node.Expression.Kind == BoundKind.MethodGroup)
                {
                    return(base.VisitMethodGroup((BoundMethodGroup)node.Expression));
                }
            }

            return(base.VisitDynamicInvocation(node));
        }
Example #3
0
        public BoundExpression VisitDynamicInvocation(BoundDynamicInvocation node, bool resultDiscarded)
        {
            var loweredArguments = VisitList(node.Arguments);

            bool                        hasImplicitReceiver;
            BoundExpression             loweredReceiver;
            ImmutableArray <TypeSymbol> typeArguments;
            string                      name;

            switch (node.Expression.Kind)
            {
            case BoundKind.MethodGroup:
                // method invocation
                BoundMethodGroup methodGroup = (BoundMethodGroup)node.Expression;
                typeArguments       = methodGroup.TypeArgumentsOpt;
                name                = methodGroup.Name;
                hasImplicitReceiver = (methodGroup.Flags & BoundMethodGroupFlags.HasImplicitReceiver) != 0;

                // Should have been eliminated during binding of dynamic invocation:
                Debug.Assert(methodGroup.ReceiverOpt == null || methodGroup.ReceiverOpt.Kind != BoundKind.TypeOrValueExpression);

                if (methodGroup.ReceiverOpt == null)
                {
                    // Calling a static method defined on an outer class via its simple name.
                    NamedTypeSymbol firstContainer = node.ApplicableMethods.First().ContainingType;
                    Debug.Assert(node.ApplicableMethods.All(m => m.IsStatic && m.ContainingType == firstContainer));

                    loweredReceiver = new BoundTypeExpression(node.Syntax, null, firstContainer);
                }
                else if (hasImplicitReceiver && factory.TopLevelMethod.IsStatic)
                {
                    // Calling a static method defined on the current class via its simple name.
                    loweredReceiver = new BoundTypeExpression(node.Syntax, null, factory.CurrentClass);
                }
                else
                {
                    loweredReceiver = VisitExpression(methodGroup.ReceiverOpt);
                }

                // If we are calling a method on a NoPIA type, we need to embed all methods/properties
                // with the matching name of this dynamic invocation.
                EmbedIfNeedTo(loweredReceiver, methodGroup.Methods, node.Syntax);

                break;

            case BoundKind.DynamicMemberAccess:
                // method invocation
                var memberAccess = (BoundDynamicMemberAccess)node.Expression;
                name                = memberAccess.Name;
                typeArguments       = memberAccess.TypeArgumentsOpt;
                loweredReceiver     = VisitExpression(memberAccess.Receiver);
                hasImplicitReceiver = false;
                break;

            default:
                // delegate invocation
                var loweredExpression = VisitExpression(node.Expression);
                return(dynamicFactory.MakeDynamicInvocation(loweredExpression, loweredArguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, resultDiscarded).ToExpression());
            }

            Debug.Assert(loweredReceiver != null);
            return(dynamicFactory.MakeDynamicMemberInvocation(
                       name,
                       loweredReceiver,
                       typeArguments,
                       loweredArguments,
                       node.ArgumentNamesOpt,
                       node.ArgumentRefKindsOpt,
                       hasImplicitReceiver,
                       resultDiscarded).ToExpression());
        }
        public BoundExpression MakeVODynamicInvokeMember(BoundExpression loweredReceiver, string name, BoundDynamicInvocation node, ImmutableArray <BoundExpression> args)
        {
            if (loweredReceiver.Type == _compilation.ArrayType())
            {
                if (_compilation.Options.Dialect.AllowASend())
                {
                    return(MakeASend(loweredReceiver, name, args));
                }
                // This should not happen because we are not converting the method call to a dynamic call, but better safe than sorry.
                return(null);
            }
            // for a method call the hierarchy is:
            // loweredReceiver = object
            // loweredReceiver.Parent = MemberAccess
            // loweredReceiver.Parent.Parent = InvocationExpression
            // loweredReceiver.Parent.Parent.Syntax.XNode = MethodCallContext
            //
            var parent = loweredReceiver.Syntax?.Parent?.Parent;
            var xnode  = parent.XNode as XSharpParser.MethodCallContext;

            if (xnode != null && xnode.HasRefArguments)
            {
                return(RewriteLateBoundCallWithRefParams(loweredReceiver, name, node, args));
            }

            var convArgs  = new ArrayBuilder <BoundExpression>();
            var usualType = _compilation.UsualType();

            foreach (var a in args)
            {
                if (a.Type == null && !a.Syntax.XIsCodeBlock)
                {
                    convArgs.Add(new BoundDefaultExpression(a.Syntax, usualType));
                }
                else
                {
                    convArgs.Add(MakeConversionNode(a, usualType, false));
                }
            }
            var aArgs = _factory.Array(usualType, convArgs.ToImmutableAndFree());

            // Note: Make sure the first parameter in __InternalSend() in the runtime is a USUAL!
            return(_factory.StaticCall(_compilation.RuntimeFunctionsType(), ReservedNames.InternalSend,
                                       MakeConversionNode(loweredReceiver, usualType, false),
                                       new BoundLiteral(loweredReceiver.Syntax, ConstantValue.Create(name), _compilation.GetSpecialType(SpecialType.System_String)),
                                       aArgs));
        }
Example #5
0
 public override BoundNode VisitDynamicInvocation(BoundDynamicInvocation node)
 {
     return(VisitDynamicInvocation(node, resultDiscarded: false));
 }