Example #1
0
        private BoundNode RewriteMethodGroupConversion(BoundConversion conversion)
        {
            // in a method group conversion, we may need to rewrite the selected method
            BoundMethodGroup operand             = (BoundMethodGroup)conversion.Operand;
            BoundExpression  originalReceiverOpt = operand.ReceiverOpt;
            BoundExpression  receiverOpt;

            if (originalReceiverOpt == null)
            {
                receiverOpt = null;
            }
            else if (!conversion.IsExtensionMethod && conversion.SymbolOpt.IsStatic)
            {
                receiverOpt = new BoundTypeExpression(originalReceiverOpt.Syntax, null, VisitType(originalReceiverOpt.Type));
            }
            else
            {
                receiverOpt = (BoundExpression)Visit(originalReceiverOpt);
            }

            TypeSymbol type = this.VisitType(conversion.Type);

            MethodSymbol method = conversion.SymbolOpt;

            //  if the original receiver was a base access and is was rewritten,
            //  change the method to point to the wrapper method
            if (BaseReferenceInReceiverWasRewritten(originalReceiverOpt, receiverOpt) && method.IsMetadataVirtual())
            {
                method = GetMethodWrapperForBaseNonVirtualCall(method, conversion.Syntax);
            }

            method  = VisitMethodSymbol(method);
            operand = operand.Update(
                TypeMap.SubstituteTypesWithoutModifiers(operand.TypeArgumentsOpt),
                method.Name,
                operand.Methods,
                operand.LookupSymbolOpt,
                operand.LookupError,
                operand.Flags,
                receiverOpt,
                operand.ResultKind);

            var conversionInfo = conversion.Conversion;

            if (conversionInfo.Method != (object)method)
            {
                conversionInfo = conversionInfo.SetConversionMethod(method);
            }

            return(conversion.Update(
                       operand,
                       conversionInfo,
                       isBaseConversion: conversion.IsBaseConversion,
                       @checked: conversion.Checked,
                       explicitCastInCode: conversion.ExplicitCastInCode,
                       constantValueOpt: conversion.ConstantValueOpt,
                       type: type));
        }
Example #2
0
        internal void Parse(BoundMethodGroup boundMethodGroup)
        {
            base.Parse(boundMethodGroup);
            if (boundMethodGroup.LookupSymbolOpt != null)
            {
                this.Method = boundMethodGroup.LookupSymbolOpt as IMethodSymbol;
            }

            if (boundMethodGroup.TypeArgumentsOpt != null)
            {
                this.TypeArgumentsOpt = boundMethodGroup.TypeArgumentsOpt.OfType <ITypeSymbol>().ToList();
            }

            if (boundMethodGroup.ReceiverOpt != null)
            {
                this.ReceiverOpt = Deserialize(boundMethodGroup.ReceiverOpt) as Expression;
            }

            if (boundMethodGroup.InstanceOpt != null)
            {
                this.InstanceOpt = Deserialize(boundMethodGroup.InstanceOpt) as Expression;
            }
        }
Example #3
0
 internal IOperation CreateDelegateTargetOperation(BoundNode delegateNode)
 {
     if (delegateNode is BoundConversion boundConversion)
     {
         if (boundConversion.ConversionKind == ConversionKind.MethodGroup)
         {
             // We don't check HasErrors on the conversion here because if we actually have a MethodGroup conversion,
             // overload resolution succeeded. The resulting method could be invalid for other reasons, but we don't
             // hide the resolved method.
             return(CreateBoundMethodGroupSingleMethodOperation((BoundMethodGroup)boundConversion.Operand,
                                                                boundConversion.SymbolOpt,
                                                                boundConversion.SuppressVirtualCalls));
         }
         else
         {
             return(Create(boundConversion.Operand));
         }
     }
     else
     {
         var boundDelegateCreationExpression = (BoundDelegateCreationExpression)delegateNode;
         if (boundDelegateCreationExpression.Argument.Kind == BoundKind.MethodGroup &&
             boundDelegateCreationExpression.MethodOpt != null)
         {
             // If this is a method binding, and a valid candidate method was found, then we want to expose
             // this child as an IMethodBindingReference. Otherwise, we want to just delegate to the standard
             // CSharpOperationFactory behavior. Note we don't check HasErrors here because if we have a method group,
             // overload resolution succeeded, even if the resulting method isn't valid for some other reason.
             BoundMethodGroup boundMethodGroup = (BoundMethodGroup)boundDelegateCreationExpression.Argument;
             return(CreateBoundMethodGroupSingleMethodOperation(boundMethodGroup, boundDelegateCreationExpression.MethodOpt, boundMethodGroup.SuppressVirtualCalls));
         }
         else
         {
             return(Create(boundDelegateCreationExpression.Argument));
         }
     }
 }
Example #4
0
 public override BoundNode VisitMethodGroup(BoundMethodGroup node)
 {
     if ((node.Flags & BoundMethodGroupFlags.HasImplicitReceiver) == BoundMethodGroupFlags.HasImplicitReceiver &&
         (object)_targetMethodThisParameter == null)
     {
         // This can happen in static contexts.
         // NOTE: LocalRewriter has already been run, so the receiver has already been replaced with an
         // appropriate type expression, if this is a static context.
         // NOTE: Don't go through VisitThisReference, because it'll produce a diagnostic.
         return(node.Update(
                    node.TypeArgumentsOpt,
                    node.Name,
                    node.Methods,
                    node.LookupSymbolOpt,
                    node.LookupError,
                    node.Flags,
                    receiverOpt: null,
                    resultKind: node.ResultKind));
     }
     else
     {
         return(base.VisitMethodGroup(node));
     }
 }
 public override BoundNode VisitMethodGroup(BoundMethodGroup node)
 {
     if ((node.Flags & BoundMethodGroupFlags.HasImplicitReceiver) == BoundMethodGroupFlags.HasImplicitReceiver &&
         (object)_targetMethodThisParameter == null)
     {
         // This can happen in static contexts.
         // NOTE: LocalRewriter has already been run, so the receiver has already been replaced with an
         // appropriate type expression, if this is a static context.
         // NOTE: Don't go through VisitThisReference, because it'll produce a diagnostic.
         return node.Update(
             node.TypeArgumentsOpt,
             node.Name,
             node.Methods,
             node.LookupSymbolOpt,
             node.LookupError,
             node.Flags,
             receiverOpt: null,
             resultKind: node.ResultKind);
     }
     else
     {
         return base.VisitMethodGroup(node);
     }
 }
Example #6
0
 public override BoundNode VisitMethodGroup(BoundMethodGroup node)
 => throw ExceptionUtilities.Unreachable;
Example #7
0
 public override object VisitMethodGroup(BoundMethodGroup node, object arg)
 {
     // this should not occur in a properly bound tree.
     VisitExpression(node.Receiver);
     return(null);
 }