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)); }
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; } }
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)); } } }
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); } }
public override BoundNode VisitMethodGroup(BoundMethodGroup node) => throw ExceptionUtilities.Unreachable;
public override object VisitMethodGroup(BoundMethodGroup node, object arg) { // this should not occur in a properly bound tree. VisitExpression(node.Receiver); return(null); }