private BoundExpression Indices(ImmutableArray <BoundExpression> expressions)
        {
            var builder = ArrayBuilder <BoundExpression> .GetInstance();

            foreach (var arg in expressions)
            {
                var index = Visit(arg);
                if (arg.Type != _int32Type)
                {
                    index = ConvertIndex(index, arg.Type, _int32Type);
                }
                builder.Add(index);
            }

            return(_bound.Array(ExpressionType, builder.ToImmutableAndFree()));
        }
예제 #2
0
        private static BoundExpressionStatement GetCreatePayloadStatement(
            ImmutableArray <SourceSpan> dynamicAnalysisSpans,
            SyntaxNode methodBodySyntax,
            LocalSymbol methodPayload,
            MethodSymbol createPayloadForMethodsSpanningSingleFile,
            MethodSymbol createPayloadForMethodsSpanningMultipleFiles,
            BoundExpression mvid,
            BoundExpression methodToken,
            BoundExpression payloadSlot,
            SyntheticBoundNodeFactory methodBodyFactory,
            DebugDocumentProvider debugDocumentProvider)
        {
            MethodSymbol    createPayloadOverload;
            BoundExpression fileIndexOrIndicesArgument;

            if (dynamicAnalysisSpans.IsEmpty)
            {
                createPayloadOverload = createPayloadForMethodsSpanningSingleFile;

                // For a compiler generated method that has no 'real' spans, we emit the index for
                // the document corresponding to the syntax node that is associated with its bound node.
                var document = GetSourceDocument(debugDocumentProvider, methodBodySyntax);
                fileIndexOrIndicesArgument = methodBodyFactory.SourceDocumentIndex(document);
            }
            else
            {
                var documents = PooledHashSet <DebugSourceDocument> .GetInstance();

                var fileIndices = ArrayBuilder <BoundExpression> .GetInstance();

                foreach (var span in dynamicAnalysisSpans)
                {
                    var document = span.Document;
                    if (documents.Add(document))
                    {
                        fileIndices.Add(methodBodyFactory.SourceDocumentIndex(document));
                    }
                }

                documents.Free();

                // At this point, we should have at least one document since we have already
                // handled the case where method has no 'real' spans (and therefore no documents) above.
                if (fileIndices.Count == 1)
                {
                    createPayloadOverload      = createPayloadForMethodsSpanningSingleFile;
                    fileIndexOrIndicesArgument = fileIndices.Single();
                }
                else
                {
                    createPayloadOverload = createPayloadForMethodsSpanningMultipleFiles;

                    // Order of elements in fileIndices should be deterministic because these
                    // elements were added based on order of spans in dynamicAnalysisSpans above.
                    fileIndexOrIndicesArgument = methodBodyFactory.Array(
                        methodBodyFactory.SpecialType(SpecialType.System_Int32), fileIndices.ToImmutable());
                }

                fileIndices.Free();
            }

            return(methodBodyFactory.Assignment(
                       methodBodyFactory.Local(methodPayload),
                       methodBodyFactory.Call(
                           null,
                           createPayloadOverload,
                           mvid,
                           methodToken,
                           fileIndexOrIndicesArgument,
                           payloadSlot,
                           methodBodyFactory.Literal(dynamicAnalysisSpans.Length))));
        }
예제 #3
0
        internal LoweredDynamicOperation MakeDynamicMemberInvocation(
            string name,
            BoundExpression loweredReceiver,
            ImmutableArray <TypeSymbol> typeArguments,
            ImmutableArray <BoundExpression> loweredArguments,
            ImmutableArray <string> argumentNames,
            ImmutableArray <RefKind> refKinds,
            bool hasImplicitReceiver,
            bool resultDiscarded)
        {
            factory.Syntax = loweredReceiver.Syntax;

            CSharpBinderFlags binderFlags = 0;

            if (hasImplicitReceiver && !factory.TopLevelMethod.IsStatic)
            {
                binderFlags |= CSharpBinderFlags.InvokeSimpleName;
            }

            TypeSymbol resultType;

            if (resultDiscarded)
            {
                binderFlags |= CSharpBinderFlags.ResultDiscarded;
                resultType   = factory.SpecialType(SpecialType.System_Void);
            }
            else
            {
                resultType = AssemblySymbol.DynamicType;
            }

            RefKind receiverRefKind;
            bool    receiverIsStaticType;

            if (loweredReceiver.Kind == BoundKind.TypeExpression)
            {
                loweredReceiver      = factory.Typeof(((BoundTypeExpression)loweredReceiver).Type);
                receiverRefKind      = RefKind.None;
                receiverIsStaticType = true;
            }
            else
            {
                receiverRefKind      = GetReceiverRefKind(loweredReceiver);
                receiverIsStaticType = false;
            }

            MethodSymbol argumentInfoFactory = GetArgumentInfoFactory();
            var          binderConstruction  = ((object)argumentInfoFactory != null) ? MakeBinderConstruction(WellKnownMember.Microsoft_CSharp_RuntimeBinder_Binder__InvokeMember, new[]
            {
                // flags:
                factory.Literal((int)binderFlags),

                // member name:
                factory.Literal(name),

                // type arguments:
                typeArguments.IsDefaultOrEmpty ?
                factory.Null(factory.WellKnownArrayType(WellKnownType.System_Type)) :
                factory.Array(factory.WellKnownType(WellKnownType.System_Type), factory.TypeOfs(typeArguments)),

                // context:
                factory.Typeof(factory.CurrentClass),

                // argument infos:
                MakeCallSiteArgumentInfos(argumentInfoFactory, loweredArguments, argumentNames, refKinds, loweredReceiver, receiverRefKind, receiverIsStaticType)
            }) : null;

            return(MakeDynamicOperation(binderConstruction, loweredReceiver, receiverRefKind, loweredArguments, refKinds, null, resultType));
        }