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