protected BoundExpression MakeConstruction(CSharpSyntaxNode node, NamedTypeSymbol toCreate, ImmutableArray <BoundExpression> args, DiagnosticBag diagnostics) { AnalyzedArguments analyzedArguments = AnalyzedArguments.GetInstance(); analyzedArguments.Arguments.AddRange(args); var result = BindClassCreationExpression(node, toCreate.Name, node, toCreate, analyzedArguments, diagnostics); result.WasCompilerGenerated = true; analyzedArguments.Free(); return(result); }
/// <summary> /// Resolve method group based on the optional delegate invoke method. /// If the invoke method is null, ignore arguments in resolution. /// </summary> private static MethodGroupResolution ResolveDelegateMethodGroup(Binder binder, BoundMethodGroup source, MethodSymbol delegateInvokeMethodOpt, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { if ((object)delegateInvokeMethodOpt != null) { var analyzedArguments = AnalyzedArguments.GetInstance(); GetDelegateArguments(source.Syntax, analyzedArguments, delegateInvokeMethodOpt.Parameters, binder.Compilation); var resolution = binder.ResolveMethodGroup(source, analyzedArguments, isMethodGroupConversion: true, inferWithDynamic: true, useSiteDiagnostics: ref useSiteDiagnostics); analyzedArguments.Free(); return(resolution); } else { return(binder.ResolveMethodGroup(source, null, isMethodGroupConversion: true, useSiteDiagnostics: ref useSiteDiagnostics)); } }
/// <summary> /// The overload resolution portion of FindForEachPatternMethod. /// </summary> private MethodSymbol PerformForEachPatternOverloadResolution(TypeSymbol patternType, ArrayBuilder <MethodSymbol> candidateMethods, bool warningsOnly, DiagnosticBag diagnostics) { ArrayBuilder <TypeSymbol> typeArguments = ArrayBuilder <TypeSymbol> .GetInstance(); AnalyzedArguments arguments = AnalyzedArguments.GetInstance(); OverloadResolutionResult <MethodSymbol> overloadResolutionResult = OverloadResolutionResult <MethodSymbol> .GetInstance(); HashSet <DiagnosticInfo> useSiteDiagnostics = null; this.OverloadResolution.MethodInvocationOverloadResolution(candidateMethods, typeArguments, arguments, overloadResolutionResult, ref useSiteDiagnostics); diagnostics.Add(syntax.Expression, useSiteDiagnostics); MethodSymbol result = null; if (overloadResolutionResult.Succeeded) { result = overloadResolutionResult.ValidResult.Member; if (result.IsStatic || result.DeclaredAccessibility != Accessibility.Public) { if (warningsOnly) { diagnostics.Add(ErrorCode.WRN_PatternStaticOrInaccessible, syntax.Expression.Location, patternType, MessageID.IDS_Collection.Localize(), result); } result = null; } else if (result.CallsAreOmitted(syntax.SyntaxTree)) { // Calls to this method are omitted in the current syntax tree, i.e it is either a partial method with no implementation part OR a conditional method whose condition is not true in this source file. // We don't want to want to allow this case, see StatementBinder::bindPatternToMethod. result = null; } } else if (overloadResolutionResult.Results.Length > 1) { if (warningsOnly) { diagnostics.Add(ErrorCode.WRN_PatternIsAmbiguous, syntax.Expression.Location, patternType, MessageID.IDS_Collection.Localize(), overloadResolutionResult.Results[0].Member, overloadResolutionResult.Results[1].Member); } } overloadResolutionResult.Free(); arguments.Free(); typeArguments.Free(); return(result); }
public Conversion MethodGroupConversion(CSharpSyntaxNode syntax, MethodGroup methodGroup, NamedTypeSymbol delegateType, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { var analyzedArguments = AnalyzedArguments.GetInstance(); var result = OverloadResolutionResult <MethodSymbol> .GetInstance(); Debug.Assert((object)delegateType.DelegateInvokeMethod != null && !delegateType.DelegateInvokeMethod.HasUseSiteError, "This method should only be called for valid delegate types"); GetDelegateArguments(syntax, analyzedArguments, delegateType.DelegateInvokeMethod.Parameters, Compilation); _binder.OverloadResolution.MethodInvocationOverloadResolution( methodGroup.Methods, methodGroup.TypeArguments, analyzedArguments, result, ref useSiteDiagnostics, isMethodGroupConversion: true); var conversion = ToConversion(result, methodGroup, delegateType); analyzedArguments.Free(); result.Free(); return(conversion); }
internal void ResolveOverloads <TMember>( ImmutableArray <TMember> members, ImmutableArray <TypeSymbol> typeArguments, ImmutableArray <ArgumentSyntax> arguments, OverloadResolutionResult <TMember> result, ref HashSet <DiagnosticInfo> useSiteDiagnostics, bool allowRefOmittedArguments) where TMember : Symbol { var methodsBuilder = ArrayBuilder <TMember> .GetInstance(members.Length); methodsBuilder.AddRange(members); var typeArgumentsBuilder = ArrayBuilder <TypeSymbol> .GetInstance(typeArguments.Length); typeArgumentsBuilder.AddRange(typeArguments); var analyzedArguments = AnalyzedArguments.GetInstance(); var unusedDiagnostics = DiagnosticBag.GetInstance(); foreach (var argumentSyntax in arguments) { var argument = this.BindExpression(argumentSyntax.Expression, unusedDiagnostics); analyzedArguments.Arguments.Add(argument); analyzedArguments.RefKinds.Add(argumentSyntax.RefOrOutKeyword.CSharpKind().GetRefKind()); analyzedArguments.Names.Add(argumentSyntax.NameColon == null ? null : argumentSyntax.NameColon.Name); } OverloadResolution.MethodOrPropertyOverloadResolution( methodsBuilder, typeArgumentsBuilder, analyzedArguments, result, isMethodGroupConversion: false, allowRefOmittedArguments: allowRefOmittedArguments, useSiteDiagnostics: ref useSiteDiagnostics); methodsBuilder.Free(); typeArgumentsBuilder.Free(); analyzedArguments.Free(); unusedDiagnostics.Free(); }
internal void ResolveOverloads <TMember>( ImmutableArray <TMember> members, ImmutableArray <TypeSymbol> typeArguments, ImmutableArray <ArgumentSyntax> arguments, OverloadResolutionResult <TMember> result, ref HashSet <DiagnosticInfo> useSiteDiagnostics, bool allowRefOmittedArguments) where TMember : Symbol { var methodsBuilder = ArrayBuilder <TMember> .GetInstance(members.Length); methodsBuilder.AddRange(members); var typeArgumentsBuilder = ArrayBuilder <TypeSymbol> .GetInstance(typeArguments.Length); typeArgumentsBuilder.AddRange(typeArguments); var analyzedArguments = AnalyzedArguments.GetInstance(); var unusedDiagnostics = DiagnosticBag.GetInstance(); foreach (var argumentSyntax in arguments) { BindArgumentAndName(analyzedArguments, unusedDiagnostics, false, argumentSyntax, allowArglist: false); } OverloadResolution.MethodOrPropertyOverloadResolution( methodsBuilder, typeArgumentsBuilder, analyzedArguments, result, isMethodGroupConversion: false, allowRefOmittedArguments: allowRefOmittedArguments, useSiteDiagnostics: ref useSiteDiagnostics); methodsBuilder.Free(); typeArgumentsBuilder.Free(); analyzedArguments.Free(); unusedDiagnostics.Free(); }
/// <summary> /// Find the Deconstruct method for the expression on the right, that will fit the number of assignable variables on the left. /// Returns an invocation expression if the Deconstruct method is found. /// If so, it outputs placeholders that were coerced to the output types of the resolved Deconstruct method. /// The overload resolution is similar to writing `receiver.Deconstruct(out var x1, out var x2, ...)`. /// </summary> private BoundExpression MakeDeconstructInvocationExpression( int numCheckedVariables, BoundExpression receiver, CSharpSyntaxNode syntax, DiagnosticBag diagnostics, out ImmutableArray <BoundDeconstructValuePlaceholder> outPlaceholders) { var receiverSyntax = receiver.Syntax; if (receiver.Type.IsDynamic()) { Error(diagnostics, ErrorCode.ERR_CannotDeconstructDynamic, receiverSyntax); outPlaceholders = default(ImmutableArray <BoundDeconstructValuePlaceholder>); return(BadExpression(receiverSyntax, receiver)); } var analyzedArguments = AnalyzedArguments.GetInstance(); var outVars = ArrayBuilder <OutDeconstructVarPendingInference> .GetInstance(numCheckedVariables); DiagnosticBag bag = null; try { for (int i = 0; i < numCheckedVariables; i++) { var variable = new OutDeconstructVarPendingInference(syntax); analyzedArguments.Arguments.Add(variable); analyzedArguments.RefKinds.Add(RefKind.Out); outVars.Add(variable); } const string methodName = "Deconstruct"; var memberAccess = BindInstanceMemberAccess( receiverSyntax, receiverSyntax, receiver, methodName, rightArity: 0, typeArgumentsSyntax: default(SeparatedSyntaxList <TypeSyntax>), typeArguments: default(ImmutableArray <TypeSymbol>), invoked: true, diagnostics: diagnostics); memberAccess = CheckValue(memberAccess, BindValueKind.RValueOrMethodGroup, diagnostics); memberAccess.WasCompilerGenerated = true; if (memberAccess.Kind != BoundKind.MethodGroup) { return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, receiver)); } // After the overload resolution completes, the last step is to coerce the arguments with inferred types. // That step returns placeholder (of correct type) instead of the outVar nodes that were passed in as arguments. // So the generated invocation expression will contain placeholders instead of those outVar nodes. // Those placeholders are also recorded in the outVar for easy access below, by the `SetInferredType` call on the outVar nodes. bag = DiagnosticBag.GetInstance(); BoundExpression result = BindMethodGroupInvocation( receiverSyntax, receiverSyntax, methodName, (BoundMethodGroup)memberAccess, analyzedArguments, bag, queryClause: null, allowUnexpandedForm: true); result.WasCompilerGenerated = true; diagnostics.AddRange(bag); if (bag.HasAnyErrors()) { return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result)); } // Verify all the parameters (except "this" for extension methods) are out parameters if (result.Kind != BoundKind.Call) { return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result)); } var deconstructMethod = ((BoundCall)result).Method; var parameters = deconstructMethod.Parameters; for (int i = (deconstructMethod.IsExtensionMethod ? 1 : 0); i < parameters.Length; i++) { if (parameters[i].RefKind != RefKind.Out) { return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result)); } } if (outVars.Any(v => (object)v.Placeholder == null)) { return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result)); } outPlaceholders = outVars.SelectAsArray(v => v.Placeholder); return(result); } finally { analyzedArguments.Free(); outVars.Free(); if (bag != null) { bag.Free(); } } }
private void BindPCallNativeAndDelegate(InvocationExpressionSyntax node, ArrayBuilder <BoundExpression> args, DiagnosticBag diagnostics, TypeSyntax type) { var XNode = node.XNode as XP.MethodCallContext; string method = XNode?.Expr.GetText(); if (string.IsNullOrEmpty(method)) { method = "PCALLNATIVE"; } if (!ValidatePCallArguments(node, args, diagnostics, method)) { return; } // Our parent is the invocation expression of the delegate AnalyzedArguments analyzedArguments = AnalyzedArguments.GetInstance(); try { var ts = FindPCallDelegateType(type as IdentifierNameSyntax); if (ts != null && ts.IsDelegateType()) { SourceDelegateMethodSymbol delmeth = ts.DelegateInvokeMethod() as SourceDelegateMethodSymbol; // create new parameters based on the parameters from out parent call var invoke = node.Parent as InvocationExpressionSyntax; var realargs = invoke.ArgumentList; var delparams = ts.DelegateParameters(); BindArgumentsAndNames(realargs, diagnostics, analyzedArguments); var builder = ArrayBuilder <ParameterSymbol> .GetInstance(); int i = 0; foreach (var expr in analyzedArguments.Arguments) { var ptype = expr.Type; if (ptype == null) { ptype = new PointerTypeSymbol(Compilation.GetSpecialType(SpecialType.System_Void)); } var parameter = new SourceSimpleParameterSymbol( delmeth, ptype, i, delparams[i].RefKind, delparams[i].Name, delparams[i].Locations); builder.Add(parameter); i++; } delmeth.InitializeParameters(builder.ToImmutableAndFree()); } else { Error(diagnostics, ErrorCode.ERR_PCallResolveGeneratedDelegate, node, method, type.ToString()); } return; } finally { analyzedArguments.Free(); } }