コード例 #1
0
        internal void ComputeReturnType()
        {
            if (!_lazyReturnType.IsNull)
            {
                return;
            }

            var        diagnostics               = DiagnosticBag.GetInstance();
            TypeSyntax returnTypeSyntax          = _syntax.ReturnType;
            TypeSymbolWithAnnotations returnType = _binder.BindType(returnTypeSyntax, diagnostics);

            if (this.IsAsync)
            {
                if (this.RefKind != RefKind.None)
                {
                    ReportBadRefToken(returnTypeSyntax, diagnostics);
                }
                else if (returnType.TypeSymbol.IsBadAsyncReturn(this.DeclaringCompilation))
                {
                    diagnostics.Add(ErrorCode.ERR_BadAsyncReturn, this.Locations[0]);
                }
            }

            var location = _syntax.ReturnType.Location;

            if (_refKind == RefKind.RefReadOnly)
            {
                DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: false);
            }

            if (returnType.NeedsNullableAttribute())
            {
                DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, 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
            }

            // span-like types are returnable in general
            if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true))
            {
                // Method or delegate cannot return type '{0}'
                diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, returnTypeSyntax.Location, returnType.TypeSymbol);
            }

            Debug.Assert(_refKind == RefKind.None ||
                         returnType.SpecialType != SpecialType.System_Void ||
                         returnTypeSyntax.HasErrors);

            lock (_declarationDiagnostics)
            {
                if (!_lazyReturnType.IsNull)
                {
                    diagnostics.Free();
                    return;
                }

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                _lazyReturnType = returnType;
            }
        }
コード例 #2
0
        protected override DiagnosticInfo ResolveInfo()
        {
            if (_possiblyRestrictedTypeSymbol.IsRestrictedType())
            {
                return(new CSDiagnosticInfo(ErrorCode.ERR_ArrayElementCantBeRefAny, _possiblyRestrictedTypeSymbol.TypeSymbol));
            }

            return(null);
        }
コード例 #3
0
        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.TypeSymbol);
            }

            if (_lazyReturnType.TypeSymbol.IsStatic)
            {
                // '{0}': static types cannot be used as return types
                diagnostics.Add(ErrorCode.ERR_ReturnTypeIsStaticClass, ReturnTypeSyntax.Location, _lazyReturnType.TypeSymbol);
            }

            this.SetReturnsVoid(_lazyReturnType.SpecialType == SpecialType.System_Void);

            // 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);
        }