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())); }
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)))); }
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)); }