Ejemplo n.º 1
0
        private SourceLocalSymbol(
            Symbol containingSymbol,
            Binder scopeBinder,
            bool allowRefKind,
            TypeSyntax typeSyntax,
            SyntaxToken identifierToken,
            LocalDeclarationKind declarationKind)
        {
            Debug.Assert(identifierToken.Kind() != SyntaxKind.None);
            Debug.Assert(declarationKind != LocalDeclarationKind.None);
            Debug.Assert(scopeBinder != null);

            this._scopeBinder      = scopeBinder;
            this._containingSymbol = containingSymbol;
            this._identifierToken  = identifierToken;
            this._typeSyntax       = allowRefKind ? typeSyntax?.SkipRef(out this._refKind) : typeSyntax;
            this._declarationKind  = declarationKind;

            // create this eagerly as it will always be needed for the EnsureSingleDefinition
            _locations = ImmutableArray.Create <Location>(identifierToken.GetLocation());

            _refEscapeScope = this._refKind == RefKind.None ?
                              scopeBinder.LocalScopeDepth :
                              Binder.ExternalScope;           // default to returnable, unless there is initializer

            // we do not know the type yet.
            // assume this is returnable in case we never get to know our type.
            _valEscapeScope = Binder.ExternalScope;
        }
Ejemplo n.º 2
0
        internal void ComputeReturnType()
        {
            if (_lazyReturnType is object)
            {
                return;
            }

            var                 diagnostics      = BindingDiagnosticBag.GetInstance(_declarationDiagnostics);
            TypeSyntax          returnTypeSyntax = Syntax.ReturnType;
            TypeWithAnnotations returnType       = _binder.BindType(returnTypeSyntax.SkipRef(), diagnostics);

            var compilation = DeclaringCompilation;

            // Skip some diagnostics when the local function is not associated with a compilation
            // (specifically, local functions nested in expressions in the EE).
            if (compilation is object)
            {
                var location = returnTypeSyntax.Location;
                if (_refKind == RefKind.RefReadOnly)
                {
                    compilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: false);
                }

                if (returnType.Type.ContainsNativeInteger())
                {
                    compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: false);
                }

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

            // span-like types are returnable in general
            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);
            }

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

            lock (_declarationDiagnostics)
            {
                if (_lazyReturnType is object)
                {
                    diagnostics.Free();
                    return;
                }

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                Interlocked.CompareExchange(ref _lazyReturnType, new TypeWithAnnotations.Boxed(returnType), null);
            }
        }
Ejemplo n.º 3
0
        internal void ComputeReturnType()
        {
            if (!_lazyReturnType.IsDefault)
            {
                return;
            }

            var        diagnostics               = DiagnosticBag.GetInstance();
            TypeSyntax returnTypeSyntax          = _syntax.ReturnType;
            TypeSymbolWithAnnotations returnType = _binder.BindType(returnTypeSyntax.SkipRef(), 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.IsDefault)
                {
                    diagnostics.Free();
                    return;
                }

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                _lazyReturnType = returnType;
            }
        }
Ejemplo n.º 4
0
        internal void ComputeReturnType()
        {
            if (!_lazyReturnType.IsNull)
            {
                return;
            }

            var        diagnostics               = DiagnosticBag.GetInstance();
            TypeSyntax returnTypeSyntax          = _syntax.ReturnType;
            TypeSymbolWithAnnotations returnType = _binder.BindType(returnTypeSyntax.SkipRef(), 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.ContainsNullableReferenceTypes())
            {
                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
            }

            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;
            }
        }
Ejemplo n.º 5
0
        private SourceLocalSymbol(
            Symbol containingSymbol,
            Binder scopeBinder,
            bool allowRefKind,
            TypeSyntax typeSyntax,
            SyntaxToken identifierToken,
            LocalDeclarationKind declarationKind)
        {
            Debug.Assert(identifierToken.Kind() != SyntaxKind.None);
            Debug.Assert(declarationKind != LocalDeclarationKind.None);
            Debug.Assert(scopeBinder != null);

            this._scopeBinder      = scopeBinder;
            this._containingSymbol = containingSymbol;
            this._identifierToken  = identifierToken;
            this._typeSyntax       = allowRefKind ? typeSyntax.SkipRef(out this._refKind) : typeSyntax;
            this._declarationKind  = declarationKind;

            // create this eagerly as it will always be needed for the EnsureSingleDefinition
            _locations = ImmutableArray.Create <Location>(identifierToken.GetLocation());
        }
Ejemplo n.º 6
0
        private TypeSymbol GetTypeSymbol()
        {
            var diagnostics = DiagnosticBag.GetInstance();

            Binder typeBinder = this.TypeSyntaxBinder;

            bool       isVar;
            RefKind    refKind;
            TypeSymbol declType = typeBinder.BindTypeOrVarKeyword(_typeSyntax.SkipRef(out refKind), diagnostics, out isVar);

            if (isVar)
            {
                TypeSymbol inferredType = InferTypeOfVarVariable(diagnostics);

                // If we got a valid result that was not void then use the inferred type
                // else create an error type.
                if ((object)inferredType != null &&
                    inferredType.SpecialType != SpecialType.System_Void)
                {
                    declType = inferredType;
                }
                else
                {
                    declType = typeBinder.CreateErrorType("var");
                }
            }

            Debug.Assert((object)declType != null);

            //
            // Note that we drop the diagnostics on the floor! That is because this code is invoked mainly in
            // IDE scenarios where we are attempting to use the types of a variable before we have processed
            // the code which causes the variable's type to be inferred. In batch compilation, on the
            // other hand, local variables have their type inferred, if necessary, in the course of binding
            // the statements of a method from top to bottom, and an inferred type is given to a variable
            // before the variable's type is used by the compiler.
            //
            diagnostics.Free();
            return(declType);
        }
Ejemplo n.º 7
0
        internal void ComputeReturnType()
        {
            if (!_lazyReturnType.IsDefault)
            {
                return;
            }

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

            var compilation = DeclaringCompilation;

            // Skip some diagnostics when the local function is not associated with a compilation
            // (specifically, local functions nested in expressions in the EE).
            if (!(compilation is null))
            {
                if (this.IsAsync)
                {
                    if (this.RefKind != RefKind.None)
                    {
                        ReportBadRefToken(returnTypeSyntax, diagnostics);
                    }
                    else if (returnType.Type.IsBadAsyncReturn(compilation))
                    {
                        diagnostics.Add(ErrorCode.ERR_BadAsyncReturn, this.Locations[0]);
                    }
                }

                var location = _syntax.ReturnType.Location;
                if (_refKind == RefKind.RefReadOnly)
                {
                    compilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: false);
                }

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

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

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

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

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                _lazyReturnType = returnType;
            }
        }