Beispiel #1
0
        internal LoweredDynamicOperation MakeDynamicOperation(
            BoundExpression binderConstruction,
            BoundExpression loweredReceiver,
            RefKind receiverRefKind,
            ImmutableArray <BoundExpression> loweredArguments,
            ImmutableArray <RefKind> refKinds,
            BoundExpression loweredRight,
            TypeSymbol resultType)
        {
            Debug.Assert(!loweredArguments.IsDefault);

            // get well-known types and members we need:
            NamedTypeSymbol delegateTypeOverMethodTypeParameters = GetDelegateType(loweredReceiver, receiverRefKind, loweredArguments, refKinds, loweredRight, resultType);
            NamedTypeSymbol callSiteTypeGeneric        = _factory.WellKnownType(WellKnownType.System_Runtime_CompilerServices_CallSite_T);
            MethodSymbol    callSiteFactoryGeneric     = _factory.WellKnownMethod(WellKnownMember.System_Runtime_CompilerServices_CallSite_T__Create);
            FieldSymbol     callSiteTargetFieldGeneric = (FieldSymbol)_factory.WellKnownMember(WellKnownMember.System_Runtime_CompilerServices_CallSite_T__Target);
            MethodSymbol    delegateInvoke;

            if (binderConstruction == null ||
                (object)delegateTypeOverMethodTypeParameters == null ||
                delegateTypeOverMethodTypeParameters.IsErrorType() ||
                (object)(delegateInvoke = delegateTypeOverMethodTypeParameters.DelegateInvokeMethod) == null ||
                callSiteTypeGeneric.IsErrorType() ||
                (object)callSiteFactoryGeneric == null ||
                (object)callSiteTargetFieldGeneric == null)
            {
                // CS1969: One or more types required to compile a dynamic expression cannot be found.
                // Dev11 reports it with source location for each dynamic operation, which results in many error messages.
                // The diagnostic that names the specific missing type or member has already been reported.
                _factory.Diagnostics.Add(ErrorCode.ERR_DynamicRequiredTypesMissing, NoLocation.Singleton);

                return(LoweredDynamicOperation.Bad(loweredReceiver, loweredArguments, loweredRight, resultType));
            }

            if ((object)_currentDynamicCallSiteContainer == null)
            {
                _currentDynamicCallSiteContainer = CreateCallSiteContainer(_factory, _methodOrdinal);
            }

            var containerDef = (SynthesizedContainer)_currentDynamicCallSiteContainer.OriginalDefinition;
            var methodToContainerTypeParametersMap = containerDef.TypeMap;

            ImmutableArray <LocalSymbol> temps = MakeTempsForDiscardArguments(ref loweredArguments);

            var callSiteType          = callSiteTypeGeneric.Construct(new[] { delegateTypeOverMethodTypeParameters });
            var callSiteFactoryMethod = callSiteFactoryGeneric.AsMember(callSiteType);
            var callSiteTargetField   = callSiteTargetFieldGeneric.AsMember(callSiteType);
            var callSiteField         = DefineCallSiteStorageSymbol(containerDef, delegateTypeOverMethodTypeParameters, methodToContainerTypeParametersMap);
            var callSiteFieldAccess   = _factory.Field(null, callSiteField);
            var callSiteArguments     = GetCallSiteArguments(callSiteFieldAccess, loweredReceiver, loweredArguments, loweredRight);

            var nullCallSite = _factory.Null(callSiteField.Type);

            var siteInitialization = _factory.Conditional(
                _factory.ObjectEqual(callSiteFieldAccess, nullCallSite),
                _factory.AssignmentExpression(callSiteFieldAccess, _factory.Call(null, callSiteFactoryMethod, binderConstruction)),
                nullCallSite,
                callSiteField.Type);

            var siteInvocation = _factory.Call(
                _factory.Field(callSiteFieldAccess, callSiteTargetField),
                delegateInvoke,
                callSiteArguments);

            return(new LoweredDynamicOperation(_factory, siteInitialization, siteInvocation, resultType, temps));
        }