public override BoundNode VisitDynamicIndexerAccess(BoundDynamicIndexerAccess node)
        {
            Debug.Assert(node.ReceiverOpt != null);

            var loweredReceiver  = VisitExpression(node.ReceiverOpt);
            var loweredArguments = VisitList(node.Arguments);

            return(MakeDynamicGetIndex(node, loweredReceiver, loweredArguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt));
        }
Exemplo n.º 2
0
        public override BoundNode VisitDynamicIndexerAccess(BoundDynamicIndexerAccess node)
        {
            if (_inExpressionLambda)
            {
                Error(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, node);
            }

            CheckReceiverIfField(node.ReceiverOpt);
            return(base.VisitDynamicIndexerAccess(node));
        }
                public override BoundNode VisitDynamicIndexerAccess(BoundDynamicIndexerAccess node)
                {
                    if (!node.ArgumentRefKindsOpt.IsDefault)
                    {
                        _mightAssignSomething = true;
                    }
                    else
                    {
                        base.VisitDynamicIndexerAccess(node);
                    }

                    return(null);
                }
        private BoundExpression MakeDynamicGetIndex(
            BoundDynamicIndexerAccess node,
            BoundExpression loweredReceiver,
            ImmutableArray <BoundExpression> loweredArguments,
            ImmutableArray <string> argumentNames,
            ImmutableArray <RefKind> refKinds)
        {
            // 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, node.ApplicableIndexers, node.Syntax);

            return(_dynamicFactory.MakeDynamicGetIndex(
                       MakeDynamicIndexerAccessReceiver(node, loweredReceiver),
                       loweredArguments,
                       argumentNames,
                       refKinds).ToExpression());
        }
        private BoundDynamicIndexerAccess TransformDynamicIndexerAccess(BoundDynamicIndexerAccess indexerAccess, ArrayBuilder <BoundExpression> stores, ArrayBuilder <LocalSymbol> temps)
        {
            BoundExpression loweredReceiver;

            if (CanChangeValueBetweenReads(indexerAccess.ReceiverOpt))
            {
                BoundAssignmentOperator assignmentToTemp;
                var temp = _factory.StoreToTemp(VisitExpression(indexerAccess.ReceiverOpt), out assignmentToTemp);
                stores.Add(assignmentToTemp);
                temps.Add(temp.LocalSymbol);
                loweredReceiver = temp;
            }
            else
            {
                loweredReceiver = indexerAccess.ReceiverOpt;
            }

            var arguments        = indexerAccess.Arguments;
            var loweredArguments = new BoundExpression[arguments.Length];

            for (int i = 0; i < arguments.Length; i++)
            {
                if (CanChangeValueBetweenReads(arguments[i]))
                {
                    BoundAssignmentOperator assignmentToTemp;
                    var temp = _factory.StoreToTemp(VisitExpression(arguments[i]), out assignmentToTemp, indexerAccess.ArgumentRefKindsOpt.RefKinds(i) != RefKind.None ? RefKind.Ref : RefKind.None);
                    stores.Add(assignmentToTemp);
                    temps.Add(temp.LocalSymbol);
                    loweredArguments[i] = temp;
                }
                else
                {
                    loweredArguments[i] = arguments[i];
                }
            }

            return(new BoundDynamicIndexerAccess(
                       indexerAccess.Syntax,
                       loweredReceiver,
                       loweredArguments.AsImmutableOrNull(),
                       indexerAccess.ArgumentNamesOpt,
                       indexerAccess.ArgumentRefKindsOpt,
                       indexerAccess.ApplicableIndexers,
                       indexerAccess.Type));
        }
        private BoundExpression MakeDynamicSetIndex(
            BoundDynamicIndexerAccess indexerAccess,
            BoundExpression loweredReceiver,
            ImmutableArray <BoundExpression> loweredArguments,
            ImmutableArray <string> argumentNames,
            ImmutableArray <RefKind> refKinds,
            BoundExpression loweredRight,
            bool isCompoundAssignment = false,
            bool isChecked            = false)
        {
            // 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, indexerAccess.ApplicableIndexers, indexerAccess.Syntax);

            return(_dynamicFactory.MakeDynamicSetIndex(
                       MakeDynamicIndexerAccessReceiver(indexerAccess, loweredReceiver),
                       loweredArguments,
                       argumentNames,
                       refKinds,
                       loweredRight,
                       isCompoundAssignment, isChecked).ToExpression());
        }
        private BoundExpression MakeDynamicIndexerAccessReceiver(BoundDynamicIndexerAccess indexerAccess, BoundExpression loweredReceiver)
        {
            BoundExpression result;

            string indexedPropertyName = indexerAccess.TryGetIndexedPropertyName();

            if (indexedPropertyName != null)
            {
                // Dev12 forces the receiver to be typed to dynamic to workaround a bug in the runtime binder.
                // See DynamicRewriter::FixupIndexedProperty:
                // "If we don't do this, then the calling object is statically typed and we pass the UseCompileTimeType to the runtime binder."
                // However, with the cast the scenarios don't work either, so we don't mimic Dev12.
                // loweredReceiver = BoundConversion.Synthesized(loweredReceiver.Syntax, loweredReceiver, Conversion.Identity, false, false, null, DynamicTypeSymbol.Instance);

                result = _dynamicFactory.MakeDynamicGetMember(loweredReceiver, indexedPropertyName, resultIndexed: true).ToExpression();
            }
            else
            {
                result = loweredReceiver;
            }

            return(result);
        }