internal SynthesizedLocal(
            MethodSymbol containingMethodOpt,
            TypeWithAnnotations type,
            SynthesizedLocalKind kind,
            SyntaxNode syntaxOpt = null,
            bool isPinned        = false,
            RefKind refKind      = RefKind.None
#if DEBUG
            ,
            [CallerLineNumber] int createdAtLineNumber = 0,
            [CallerFilePath] string createdAtFilePath  = null
#endif
            )
        {
            Debug.Assert(!type.IsVoidType());
            Debug.Assert(!kind.IsLongLived() || syntaxOpt != null);
            Debug.Assert(refKind != RefKind.Out);
            Debug.Assert(containingMethodOpt is null || containingMethodOpt.DeclaringCompilation is not null);

            _containingMethodOpt = containingMethodOpt;
            _type      = type;
            _kind      = kind;
            _syntaxOpt = syntaxOpt;
            _isPinned  = isPinned;
            _refKind   = refKind;

#if DEBUG
            _createdAtLineNumber = createdAtLineNumber;
            _createdAtFilePath   = createdAtFilePath;
#endif
        }
 internal ScriptEntryPoint(NamedTypeSymbol containingType, TypeWithAnnotations returnType) :
     base(containingType)
 {
     Debug.Assert(containingType.IsScriptClass);
     Debug.Assert(returnType.IsVoidType());
     _returnType = returnType;
 }
        protected override void MethodChecks(BindingDiagnosticBag diagnostics)
        {
            (_lazyReturnType, _lazyParameters) = MakeParametersAndBindReturnType(diagnostics);

            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);
        }
Beispiel #4
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);
            }
        }
        internal void ComputeReturnType()
        {
            if (!_lazyReturnType.IsDefault)
            {
                return;
            }

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

            if (this.IsAsync)
            {
                if (this.RefKind != RefKind.None)
                {
                    ReportBadRefToken(returnTypeSyntax, diagnostics);
                }
                else if (returnType.Type.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.Type);
            }

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

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

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                _lazyReturnType = returnType;
            }
        }
            internal SubmissionEntryPoint(NamedTypeSymbol containingType, TypeWithAnnotations returnType, TypeSymbol submissionArrayType) :
                base(containingType)
            {
                Debug.Assert(containingType.IsSubmissionClass);
                Debug.Assert(!returnType.IsVoidType());
                _parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this,
                    TypeWithAnnotations.Create(submissionArrayType), 0, RefKind.None, "submissionArray"));

                _returnType = returnType;
            }
Beispiel #7
0
 protected SourceDelegateMethodSymbol(
     SourceMemberContainerTypeSymbol delegateType,
     TypeWithAnnotations returnType,
     DelegateDeclarationSyntax syntax,
     MethodKind methodKind,
     DeclarationModifiers declarationModifiers)
     : base(delegateType, syntax.GetReference(), location: syntax.Identifier.GetLocation(), isIterator: false)
 {
     _returnType = returnType;
     this.MakeFlags(methodKind, declarationModifiers, _returnType.IsVoidType(), isExtensionMethod: false);
 }
Beispiel #8
0
        protected override void MethodChecks(DiagnosticBag diagnostics)
        {
            // These values may not be final, but we need to have something set here in the
            // event that we need to find the overridden accessor.
            _lazyParameters         = ComputeParameters(diagnostics);
            _lazyReturnType         = ComputeReturnType(diagnostics);
            _lazyRefCustomModifiers = ImmutableArray <CustomModifier> .Empty;

            if (_explicitInterfaceImplementations.Length > 0)
            {
                Debug.Assert(_explicitInterfaceImplementations.Length == 1);
                MethodSymbol implementedMethod = _explicitInterfaceImplementations[0];
                CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
                                                              out _lazyRefCustomModifiers,
                                                              out _lazyParameters, alsoCopyParamsModifier: false);
            }
            else if (this.IsOverride)
            {
                // This will cause another call to SourceMethodSymbol.LazyMethodChecks,
                // but that method already handles reentrancy for exactly this case.
                MethodSymbol overriddenMethod = this.OverriddenMethod;
                if ((object)overriddenMethod != null)
                {
                    CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
                                                                  out _lazyRefCustomModifiers,
                                                                  out _lazyParameters, alsoCopyParamsModifier: true);
                }
            }
            else if (!_lazyReturnType.IsVoidType())
            {
                PropertySymbol associatedProperty = _property;
                var            type = associatedProperty.TypeWithAnnotations;
                _lazyReturnType = _lazyReturnType.WithTypeAndModifiers(
                    CustomModifierUtils.CopyTypeCustomModifiers(type.Type, _lazyReturnType.Type, this.ContainingAssembly),
                    type.CustomModifiers);
                _lazyRefCustomModifiers = associatedProperty.RefCustomModifiers;
            }
        }
        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 MethodSymbol?MethodChecks(TypeWithAnnotations returnType, ImmutableArray <ParameterSymbol> parameters, BindingDiagnosticBag diagnostics)
        {
            _lazyReturnType = returnType;
            _lazyParameters = parameters;

            // set ReturnsVoid flag
            this.SetReturnsVoid(_lazyReturnType.IsVoidType());

            this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);
            this.CheckFileTypeUsage(_lazyReturnType, _lazyParameters, diagnostics);

            var location = locations[0];

            // Checks taken from MemberDefiner::defineMethod
            if (this.Name == WellKnownMemberNames.DestructorName && this.ParameterCount == 0 && this.Arity == 0 && this.ReturnsVoid)
            {
                diagnostics.Add(ErrorCode.WRN_FinalizeMethod, location);
            }

            ExtensionMethodChecks(diagnostics);

            if (IsPartial)
            {
                if (MethodKind == MethodKind.ExplicitInterfaceImplementation)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, location);
                }

                if (!ContainingType.IsPartial())
                {
                    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 SourceMemberContainerTypeSymbol.SynthesizeInterfaceMemberImplementation).

            // This value may not be correct, but we need something while we compute this.OverriddenMethod.
            // May be re-assigned below.
            Debug.Assert(_lazyReturnType.CustomModifiers.IsEmpty);
            _lazyRefCustomModifiers = ImmutableArray <CustomModifier> .Empty;

            MethodSymbol?overriddenOrExplicitlyImplementedMethod = null;

            // 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 (MethodKind != MethodKind.ExplicitInterfaceImplementation)
            {
                Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                // 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.
                    overriddenOrExplicitlyImplementedMethod = this.OverriddenMethod;

                    if ((object)overriddenOrExplicitlyImplementedMethod != null)
                    {
                        CustomModifierUtils.CopyMethodCustomModifiers(overriddenOrExplicitlyImplementedMethod, this, out _lazyReturnType,
                                                                      out _lazyRefCustomModifiers,
                                                                      out _lazyParameters, alsoCopyParamsModifier: true);
                    }
                }
                else if (RefKind == RefKind.RefReadOnly)
                {
                    var modifierType = Binder.GetWellKnownType(DeclaringCompilation, WellKnownType.System_Runtime_InteropServices_InAttribute, diagnostics, ReturnTypeLocation);

                    _lazyRefCustomModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType));
                }
            }
            else if (ExplicitInterfaceType is not null)
            {
                //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation)
                overriddenOrExplicitlyImplementedMethod = FindExplicitlyImplementedMethod(diagnostics);

                if (overriddenOrExplicitlyImplementedMethod is not null)
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(overriddenOrExplicitlyImplementedMethod);

                    CustomModifierUtils.CopyMethodCustomModifiers(overriddenOrExplicitlyImplementedMethod, this, out _lazyReturnType,
                                                                  out _lazyRefCustomModifiers,
                                                                  out _lazyParameters, alsoCopyParamsModifier: false);
                    this.FindExplicitlyImplementedMemberVerification(overriddenOrExplicitlyImplementedMethod, diagnostics);
                    TypeSymbol.CheckNullableReferenceTypeAndScopedMismatchOnImplementingMember(this.ContainingType, this, overriddenOrExplicitlyImplementedMethod, isExplicit: true, diagnostics);
                }
                else
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                    Debug.Assert(_lazyReturnType.CustomModifiers.IsEmpty);
                }
            }

            return(overriddenOrExplicitlyImplementedMethod);
        }