private void ComputeParameters() { if (_lazyParameters != null) { return; } SyntaxToken arglistToken; var diagnostics = DiagnosticBag.GetInstance(); var parameters = ParameterHelpers.MakeParameters( _binder, this, _syntax.ParameterList, arglistToken: out arglistToken, allowRefOrOut: true, allowThis: true, addRefReadOnlyModifier: false, diagnostics: diagnostics); ParameterHelpers.EnsureIsReadOnlyAttributeExists(parameters, diagnostics, modifyCompilation: false); ParameterHelpers.EnsureNullableAttributeExists(parameters, diagnostics, modifyCompilation: false); // Note: we don't need to warn on annotations used without NonNullTypes context for local functions, as this is handled in binding already var isVararg = arglistToken.Kind() == SyntaxKind.ArgListKeyword; if (isVararg) { diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation()); } if (IsAsync) { SourceOrdinaryMethodSymbol.ReportAsyncParameterErrors(parameters, diagnostics, this.Locations[0]); } lock (_declarationDiagnostics) { if (_lazyParameters != null) { diagnostics.Free(); return; } _declarationDiagnostics.AddRangeAndFree(diagnostics); _lazyIsVarArg = isVararg; _lazyParameters = parameters; } }
protected sealed override void MethodChecks(BindingDiagnosticBag diagnostics) { var syntax = (CSharpSyntaxNode)syntaxReferenceOpt.GetSyntax(); var binderFactory = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree); ParameterListSyntax parameterList = GetParameterList(); // NOTE: if we asked for the binder for the body of the constructor, we'd risk a stack overflow because // we might still be constructing the member list of the containing type. However, getting the binder // for the parameters should be safe. var bodyBinder = binderFactory.GetBinder(parameterList, syntax, this).WithContainingMemberOrLambda(this); // Constraint checking for parameter and return types must be delayed until // the method has been added to the containing type member list since // evaluating the constraints may depend on accessing this method from // the container (comparing this method to others to find overrides for // instance). Constraints are checked in AfterAddingTypeMembersChecks. var signatureBinder = bodyBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); SyntaxToken arglistToken; _lazyParameters = ParameterHelpers.MakeParameters( signatureBinder, this, parameterList, out arglistToken, allowRefOrOut: AllowRefOrOut, allowThis: false, addRefReadOnlyModifier: false, diagnostics: diagnostics); _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); _lazyReturnType = TypeWithAnnotations.Create(bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax)); var location = this.Locations[0]; // Don't report ERR_StaticConstParam if the ctor symbol name doesn't match the containing type name. // This avoids extra unnecessary errors. // There will already be a diagnostic saying Method must have a return type. if (MethodKind == MethodKind.StaticConstructor && (_lazyParameters.Length != 0) && ContainingType.Name == ((ConstructorDeclarationSyntax)this.SyntaxNode).Identifier.ValueText) { diagnostics.Add(ErrorCode.ERR_StaticConstParam, location, this); } this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics); this.CheckFileTypeUsage(_lazyReturnType, _lazyParameters, diagnostics); if (_lazyIsVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams)) { diagnostics.Add(ErrorCode.ERR_BadVarargs, location); } }
private void ComputeParameters() { if (_lazyParameters != null) { return; } SyntaxToken arglistToken; var diagnostics = BindingDiagnosticBag.GetInstance(_declarationDiagnostics); var parameters = ParameterHelpers.MakeParameters( WithTypeParametersBinder, this, this.Syntax.ParameterList, arglistToken: out arglistToken, allowRefOrOut: true, allowThis: true, addRefReadOnlyModifier: false, diagnostics: diagnostics); var compilation = DeclaringCompilation; ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false); ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false); ParameterHelpers.EnsureLifetimeAnnotationAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false); ParameterHelpers.EnsureNullableAttributeExists(compilation, this, parameters, diagnostics, modifyCompilation: false); // Note: we don't need to warn on annotations used in #nullable disable context for local functions, as this is handled in binding already var isVararg = arglistToken.Kind() == SyntaxKind.ArgListKeyword; if (isVararg) { diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation()); } lock (_declarationDiagnostics) { if (_lazyParameters != null) { diagnostics.Free(); return; } _declarationDiagnostics.AddRangeAndFree(diagnostics); _lazyIsVarArg = isVararg; _lazyParameters = parameters; } }
private void ComputeParameters() { if (!_parameters.IsDefault) { return; } var diagnostics = DiagnosticBag.GetInstance(); SyntaxToken arglistToken; _parameters = ParameterHelpers.MakeParameters(_binder, this, _syntax.ParameterList, true, out arglistToken, diagnostics, true); _isVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); if (diagnostics.IsEmptyWithoutResolution) { SourceMemberMethodSymbol.ReportAsyncParameterErrors(this, diagnostics, this.Locations[0]); } AddDiagnostics(diagnostics.ToReadOnlyAndFree()); }
private void ComputeParameters() { if (_lazyParameters != null) { return; } SyntaxToken arglistToken; var diagnostics = DiagnosticBag.GetInstance(); var parameters = ParameterHelpers.MakeParameters( _binder, this, _syntax.ParameterList, arglistToken: out arglistToken, allowRefOrOut: true, allowThis: true, diagnostics: diagnostics); var isVararg = arglistToken.Kind() == SyntaxKind.ArgListKeyword; if (isVararg) { diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation()); } if (IsAsync) { SourceMemberMethodSymbol.ReportAsyncParameterErrors(parameters, diagnostics, this.Locations[0]); } lock (_declarationDiagnostics) { if (_lazyParameters != null) { diagnostics.Free(); return; } _declarationDiagnostics.AddRangeAndFree(diagnostics); _lazyIsVarArg = isVararg; _lazyParameters = parameters; } }
private void ComputeParameters() { if (_lazyParametersAndDiagnostics != null) { return; } var diagnostics = DiagnosticBag.GetInstance(); SyntaxToken arglistToken; var parameters = ParameterHelpers.MakeParameters(_binder, this, _syntax.ParameterList, true, out arglistToken, diagnostics, true); var isVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); if (IsAsync && diagnostics.IsEmptyWithoutResolution) { SourceMemberMethodSymbol.ReportAsyncParameterErrors(parameters, diagnostics, this.Locations[0]); } var value = new ParametersAndDiagnostics(parameters, isVararg, diagnostics.ToReadOnlyAndFree()); Interlocked.CompareExchange(ref _lazyParametersAndDiagnostics, value, null); }
internal InvokeMethod( SourceMemberContainerTypeSymbol delegateType, TypeSymbol returnType, DelegateDeclarationSyntax syntax, Binder binder, DiagnosticBag diagnostics) : base(delegateType, returnType, syntax, MethodKind.DelegateInvoke, DeclarationModifiers.Virtual | DeclarationModifiers.Public) { SyntaxToken arglistToken; var parameters = ParameterHelpers.MakeParameters(binder, this, syntax.ParameterList, true, out arglistToken, diagnostics); if (arglistToken.Kind() == SyntaxKind.ArgListKeyword) { // This is a parse-time error in the native compiler; it is a semantic analysis error in Roslyn. // error CS1669: __arglist is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken)); } InitializeParameters(parameters); }
internal InvokeMethod( SourceMemberContainerTypeSymbol delegateType, RefKind refKind, TypeWithAnnotations returnType, DelegateDeclarationSyntax syntax, Binder binder, DiagnosticBag diagnostics) : base(delegateType, returnType, syntax, MethodKind.DelegateInvoke, DeclarationModifiers.Virtual | DeclarationModifiers.Public) { this._refKind = refKind; SyntaxToken arglistToken; var parameters = ParameterHelpers.MakeParameters( binder, this, syntax.ParameterList, out arglistToken, allowRefOrOut: true, allowThis: false, addRefReadOnlyModifier: true, diagnostics: diagnostics); if (arglistToken.Kind() == SyntaxKind.ArgListKeyword) { // This is a parse-time error in the native compiler; it is a semantic analysis error in Roslyn. // error CS1669: __arglist is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken)); } if (_refKind == RefKind.RefReadOnly) { var modifierType = binder.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_InAttribute, diagnostics, syntax.ReturnType); _refCustomModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType)); } else { _refCustomModifiers = ImmutableArray <CustomModifier> .Empty; } InitializeParameters(parameters); }
protected override void MethodChecks(DiagnosticBag diagnostics) { var syntax = GetSyntax(); var binderFactory = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree); ParameterListSyntax parameterList = syntax.ParameterList; // NOTE: if we asked for the binder for the body of the constructor, we'd risk a stack overflow because // we might still be constructing the member list of the containing type. However, getting the binder // for the parameters should be safe. var bodyBinder = binderFactory.GetBinder(parameterList, syntax, this).WithContainingMemberOrLambda(this); SyntaxToken arglistToken; _lazyParameters = ParameterHelpers.MakeParameters( bodyBinder, this, parameterList, out arglistToken, allowRefOrOut: true, allowThis: false, addRefReadOnlyModifier: false, diagnostics: diagnostics); _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); _lazyReturnType = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax)); var location = this.Locations[0]; if (MethodKind == MethodKind.StaticConstructor && (_lazyParameters.Length != 0)) { diagnostics.Add(ErrorCode.ERR_StaticConstParam, location, this); } this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics); if (_lazyIsVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams)) { diagnostics.Add(ErrorCode.ERR_BadVarargs, location); } }
private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics) { SyntaxToken arglistToken; // Constraint checking for parameter and return types must be delayed until // the method has been added to the containing type member list since // evaluating the constraints may depend on accessing this method from // the container (comparing this method to others to find overrides for // instance). Constraints are checked in AfterAddingTypeMembersChecks. var signatureBinder = withTypeParamsBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); _lazyParameters = ParameterHelpers.MakeParameters(signatureBinder, this, syntax.ParameterList, true, out arglistToken, diagnostics, false); _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); RefKind refKind; var returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind); _lazyReturnType = signatureBinder.BindType(returnTypeSyntax, diagnostics); if (_lazyReturnType.IsRestrictedType()) { if (_lazyReturnType.SpecialType == SpecialType.System_TypedReference && (this.ContainingType.SpecialType == SpecialType.System_TypedReference || this.ContainingType.SpecialType == SpecialType.System_ArgIterator)) { // Two special cases: methods in the special types TypedReference and ArgIterator are allowed to return TypedReference } else { // Method or delegate cannot return type '{0}' diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, syntax.ReturnType.Location, _lazyReturnType); } } var returnsVoid = _lazyReturnType.SpecialType == SpecialType.System_Void; if (this.RefKind != RefKind.None && returnsVoid) { Debug.Assert(returnTypeSyntax.HasErrors); } // set ReturnsVoid flag this.SetReturnsVoid(returnsVoid); var location = this.Locations[0]; this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics); // Checks taken from MemberDefiner::defineMethod if (this.Name == WellKnownMemberNames.DestructorName && this.ParameterCount == 0 && this.Arity == 0 && this.ReturnsVoid) { diagnostics.Add(ErrorCode.WRN_FinalizeMethod, location); } // errors relevant for extension methods if (IsExtensionMethod) { var parameter0Type = this.Parameters[0].Type; if (!parameter0Type.IsValidExtensionParameterType()) { // Duplicate Dev10 behavior by selecting the parameter type. var parameterSyntax = syntax.ParameterList.Parameters[0]; Debug.Assert(parameterSyntax.Type != null); var loc = parameterSyntax.Type.Location; diagnostics.Add(ErrorCode.ERR_BadTypeforThis, loc, parameter0Type); } else if ((object)ContainingType.ContainingType != null) { diagnostics.Add(ErrorCode.ERR_ExtensionMethodsDecl, location, ContainingType.Name); } else if (!ContainingType.IsScriptClass && !(ContainingType.IsStatic && ContainingType.Arity == 0)) { // Duplicate Dev10 behavior by selecting the containing type identifier. However if there // is no containing type (in the interactive case for instance), select the method identifier. var typeDecl = syntax.Parent as TypeDeclarationSyntax; var identifier = (typeDecl != null) ? typeDecl.Identifier : syntax.Identifier; var loc = identifier.GetLocation(); diagnostics.Add(ErrorCode.ERR_BadExtensionAgg, loc); } else if (!IsStatic) { diagnostics.Add(ErrorCode.ERR_BadExtensionMeth, location); } else { // Verify ExtensionAttribute is available. var attributeConstructor = withTypeParamsBinder.Compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor); if ((object)attributeConstructor == null) { var memberDescriptor = WellKnownMembers.GetDescriptor(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor); // do not use Binder.ReportUseSiteErrorForAttributeCtor in this case, because we'll need to report a special error id, not a generic use site error. diagnostics.Add( ErrorCode.ERR_ExtensionAttrNotFound, syntax.ParameterList.Parameters[0].Modifiers.FirstOrDefault(SyntaxKind.ThisKeyword).GetLocation(), memberDescriptor.DeclaringTypeMetadataName); } } } if (this.MethodKind == MethodKind.UserDefinedOperator) { foreach (var p in this.Parameters) { if (p.RefKind != RefKind.None) { diagnostics.Add(ErrorCode.ERR_IllegalRefParam, location); break; } } } else if (IsPartial) { // check that there are no out parameters in a partial foreach (var p in this.Parameters) { if (p.RefKind == RefKind.Out) { diagnostics.Add(ErrorCode.ERR_PartialMethodCannotHaveOutParameters, location); break; } } if (MethodKind == MethodKind.ExplicitInterfaceImplementation) { diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, location); } if (!ContainingType.IsPartial() || ContainingType.IsInterface) { diagnostics.Add(ErrorCode.ERR_PartialMethodOnlyInPartialClass, location); } } if (!IsPartial) { LazyAsyncMethodChecks(CancellationToken.None); Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks)); } // The runtime will not treat this method as an override or implementation of another // method unless both the signatures and the custom modifiers match. Hence, in the // case of overrides and *explicit* implementations, we need to copy the custom modifiers // that are in the signature of the overridden/implemented method. (From source, we know // that there can only be one such method, so there are no conflicts.) This is // unnecessary for implicit implementations because, if the custom modifiers don't match, // we'll insert a bridge method (an explicit implementation that delegates to the implicit // implementation) with the correct custom modifiers // (see SourceNamedTypeSymbol.ImplementInterfaceMember). // Note: we're checking if the syntax indicates explicit implementation rather, // than if explicitInterfaceType is null because we don't want to look for an // overridden property if this is supposed to be an explicit implementation. if (syntax.ExplicitInterfaceSpecifier == null) { Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault); _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty; // This value may not be correct, but we need something while we compute this.OverriddenMethod. // May be re-assigned below. Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault); Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0); _lazyReturnTypeCustomModifiers = ImmutableArray <CustomModifier> .Empty; _lazyCountOfCustomModifiersPrecedingByRef = 0; // If this method is an override, we may need to copy custom modifiers from // the overridden method (so that the runtime will recognize it as an override). // We check for this case here, while we can still modify the parameters and // return type without losing the appearance of immutability. if (this.IsOverride) { // This computation will necessarily be performed with partially incomplete // information. There is no way we can determine the complete signature // (i.e. including custom modifiers) until we have found the method that // this method overrides. To accommodate this, MethodSymbol.OverriddenOrHiddenMembers // is written to allow relaxed matching of custom modifiers for source methods, // on the assumption that they will be updated appropriately. MethodSymbol overriddenMethod = this.OverriddenMethod; if ((object)overriddenMethod != null) { CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef, out _lazyParameters, alsoCopyParamsModifier: true); } } } else if ((object)_explicitInterfaceType != null) { //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation) MethodSymbol implementedMethod = this.FindExplicitlyImplementedMethod(_explicitInterfaceType, syntax.Identifier.ValueText, syntax.ExplicitInterfaceSpecifier, diagnostics); if ((object)implementedMethod != null) { Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault); _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(implementedMethod); CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef, out _lazyParameters, alsoCopyParamsModifier: false); } else { Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault); _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty; Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault); Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0); _lazyReturnTypeCustomModifiers = ImmutableArray <CustomModifier> .Empty; _lazyCountOfCustomModifiersPrecedingByRef = 0; } } CheckModifiers(location, diagnostics); }
protected override void MethodChecks(DiagnosticBag diagnostics) { var binder = this.DeclaringCompilation. GetBinderFactory(syntaxReferenceOpt.SyntaxTree).GetBinder(ReturnTypeSyntax, GetSyntax(), this); SyntaxToken arglistToken; var signatureBinder = binder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks); _lazyParameters = ParameterHelpers.MakeParameters( signatureBinder, this, ParameterListSyntax, out arglistToken, allowRefOrOut: true, allowThis: false, addRefReadOnlyModifier: false, diagnostics: diagnostics); if (arglistToken.Kind() == SyntaxKind.ArgListKeyword) { // This is a parse-time error in the native compiler; it is a semantic analysis error in Roslyn. // error CS1669: __arglist is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken)); // Regardless of whether __arglist appears in the source code, we do not mark // the operator method as being a varargs method. } _lazyReturnType = signatureBinder.BindType(ReturnTypeSyntax, diagnostics); // restricted types cannot be returned. // NOTE: Span-like types can be returned (if expression is returnable). if (_lazyReturnType.IsRestrictedType(ignoreSpanLikeTypes: true)) { // Method or delegate cannot return type '{0}' diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, ReturnTypeSyntax.Location, _lazyReturnType.Type); } if (_lazyReturnType.Type.IsStatic) { // '{0}': static types cannot be used as return types diagnostics.Add(ErrorCode.ERR_ReturnTypeIsStaticClass, ReturnTypeSyntax.Location, _lazyReturnType.Type); } this.SetReturnsVoid(_lazyReturnType.IsVoidType()); // If we have a conversion/equality/inequality operator in an interface or static class then we already // have reported that fact as an error. No need to cascade the error further. if ((this.ContainingType.IsInterfaceType() && (MethodKind == MethodKind.Conversion || Name == WellKnownMemberNames.EqualityOperatorName || Name == WellKnownMemberNames.InequalityOperatorName)) || this.ContainingType.IsStatic) { return; } // SPEC: All types referenced in an operator declaration must be at least as accessible // SPEC: as the operator itself. CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics); CheckValueParameters(diagnostics); CheckOperatorSignatures(diagnostics); }
protected override void MethodChecks(DiagnosticBag diagnostics) { var binder = this.DeclaringCompilation. GetBinderFactory(syntaxReference.SyntaxTree).GetBinder(ReturnTypeSyntax); SyntaxToken arglistToken; var signatureBinder = binder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks); this.lazyParameters = ParameterHelpers.MakeParameters( signatureBinder, this, ParameterListSyntax, true, out arglistToken, diagnostics); if (arglistToken.CSharpKind() == SyntaxKind.ArgListKeyword) { // This is a parse-time error in the native compiler; it is a semantic analysis error in Roslyn. // error CS1669: __arglist is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken)); // Regardless of whether __arglist appears in the source code, we do not mark // the operator method as being a varargs method. } this.lazyReturnType = signatureBinder.BindType(ReturnTypeSyntax, diagnostics); if (this.lazyReturnType.IsRestrictedType()) { // Method or delegate cannot return type '{0}' diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, ReturnTypeSyntax.Location, this.lazyReturnType); } if (this.lazyReturnType.IsStatic) { // '{0}': static types cannot be used as return types diagnostics.Add(ErrorCode.ERR_ReturnTypeIsStaticClass, ReturnTypeSyntax.Location, this.lazyReturnType); } this.flags |= MakeFlags( MethodKind, DeclarationModifiers, this.lazyReturnType.SpecialType == SpecialType.System_Void, IsExtensionMethod); // If we have an operator in an interface or static class then we already // have reported that fact as an error. No need to cascade the error further. if (this.ContainingType.IsInterfaceType() || this.ContainingType.IsStatic) { return; } // SPEC: All types referenced in an operator declaration must be at least as accessible // SPEC: as the operator itself. CheckEffectiveAccessibility(lazyReturnType, lazyParameters, diagnostics); CheckValueParameters(diagnostics); CheckOperatorSignatures(diagnostics); }
protected (TypeWithAnnotations ReturnType, ImmutableArray <ParameterSymbol> Parameters) MakeParametersAndBindReturnType( BaseMethodDeclarationSyntax declarationSyntax, TypeSyntax returnTypeSyntax, BindingDiagnosticBag diagnostics ) { TypeWithAnnotations returnType; ImmutableArray <ParameterSymbol> parameters; var binder = this.DeclaringCompilation .GetBinderFactory(declarationSyntax.SyntaxTree) .GetBinder(returnTypeSyntax, declarationSyntax, this); SyntaxToken arglistToken; var signatureBinder = binder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks); parameters = ParameterHelpers.MakeParameters( signatureBinder, this, declarationSyntax.ParameterList, out arglistToken, allowRefOrOut: true, allowThis: false, addRefReadOnlyModifier: false, diagnostics: diagnostics ); if (arglistToken.Kind() == SyntaxKind.ArgListKeyword) { // This is a parse-time error in the native compiler; it is a semantic analysis error in Roslyn. // error CS1669: __arglist is not valid in this context diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken)); // Regardless of whether __arglist appears in the source code, we do not mark // the operator method as being a varargs method. } returnType = signatureBinder.BindType(returnTypeSyntax, diagnostics); // restricted types cannot be returned. // NOTE: Span-like types can be returned (if expression is returnable). if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true)) { // The return type of a method, delegate, or function pointer cannot be '{0}' diagnostics.Add( ErrorCode.ERR_MethodReturnCantBeRefAny, returnTypeSyntax.Location, returnType.Type ); } if (returnType.Type.IsStatic) { // Operators in interfaces was introduced in C# 8, so there's no need to be specially concerned about // maintaining backcompat with the native compiler bug around interfaces. // '{0}': static types cannot be used as return types diagnostics.Add( ErrorFacts.GetStaticClassReturnCode(useWarning: false), returnTypeSyntax.Location, returnType.Type ); } return(returnType, parameters); }