diff --git a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs index 7c8842384cb5c..94d75be8c52a3 100644 --- a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs +++ b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/SynthesizedClosureMethod.cs @@ -218,7 +218,6 @@ protected override ImmutableArray ExtraSynthesizedRefParameters internal override bool InheritsBaseMethodAttributes => true; internal override bool GenerateDebugInfo => !this.IsAsync; - internal override bool IsExpressionBodied => false; internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree) { diff --git a/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs b/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs index 409c5e74098a2..4496b6fe86b11 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs @@ -46,11 +46,16 @@ protected SynthesizedMethodBaseSymbol(NamedTypeSymbol containingType, this.MakeFlags( methodKind: MethodKind.Ordinary, + refKind: baseMethod.RefKind, declarationModifiers: declarationModifiers, returnsVoid: baseMethod.ReturnsVoid, + // Consider synthesized methods to always have bodies. + hasAnyBody: true, isExtensionMethod: false, isNullableAnalysisEnabled: false, - isMetadataVirtualIgnoringModifiers: false); + isVarArg: baseMethod.IsVararg, + isMetadataVirtualIgnoringModifiers: false, + isExpressionBodied: false); } protected void AssignTypeMapAndTypeParameters(TypeMap typeMap, ImmutableArray typeParameters) @@ -196,11 +201,6 @@ internal sealed override IEnumerable GetSecurityInformation() #nullable disable - public sealed override RefKind RefKind - { - get { return this.BaseMethod.RefKind; } - } - public sealed override TypeWithAnnotations ReturnTypeWithAnnotations { get { return this.TypeMap.SubstituteType(this.BaseMethod.OriginalDefinition.ReturnTypeWithAnnotations); } @@ -212,11 +212,6 @@ public sealed override TypeWithAnnotations ReturnTypeWithAnnotations public sealed override FlowAnalysisAnnotations FlowAnalysisAnnotations => FlowAnalysisAnnotations.None; - public sealed override bool IsVararg - { - get { return this.BaseMethod.IsVararg; } - } - public sealed override string Name { get { return _name; } @@ -226,10 +221,5 @@ public sealed override bool IsImplicitlyDeclared { get { return true; } } - - internal override bool IsExpressionBodied - { - get { return false; } - } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs index 38371b2442a00..2119ddccd1841 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs @@ -12,7 +12,6 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols { internal sealed class SourceConstructorSymbol : SourceConstructorSymbolBase { - private readonly bool _isExpressionBodied; private readonly bool _hasThisInitializer; public static SourceConstructorSymbol CreateConstructorSymbol( @@ -35,14 +34,16 @@ private SourceConstructorSymbol( base(containingType, location, syntax, SyntaxFacts.HasYieldOperations(syntax)) { bool hasBlockBody = syntax.Body != null; - _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; - bool hasBody = hasBlockBody || _isExpressionBodied; + bool isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; + bool hasAnyBody = hasBlockBody || isExpressionBodied; _hasThisInitializer = syntax.Initializer?.Kind() == SyntaxKind.ThisConstructorInitializer; bool modifierErrors; - var declarationModifiers = this.MakeModifiers(syntax.Modifiers, methodKind, hasBody, location, diagnostics, out modifierErrors); - this.MakeFlags(methodKind, declarationModifiers, returnsVoid: true, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled); + var declarationModifiers = this.MakeModifiers(syntax.Modifiers, methodKind, hasAnyBody, location, diagnostics, out modifierErrors); + this.MakeFlags( + methodKind, RefKind.None, declarationModifiers, returnsVoid: true, hasAnyBody: hasAnyBody, isExpressionBodied: isExpressionBodied, + isExtensionMethod: false, isVarArg: syntax.ParameterList.Parameters.Any(static p => p.IsArgList), isNullableAnalysisEnabled: isNullableAnalysisEnabled); if (syntax.Identifier.ValueText != containingType.Name) { @@ -57,7 +58,7 @@ private SourceConstructorSymbol( diagnostics.Add(ErrorCode.ERR_ExternHasConstructorInitializer, location, this); } - if (hasBody) + if (hasAnyBody) { diagnostics.Add(ErrorCode.ERR_ExternHasBody, location, this); } @@ -65,14 +66,14 @@ private SourceConstructorSymbol( if (methodKind == MethodKind.StaticConstructor) { - CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasBody, diagnostics); + CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasAnyBody, diagnostics); } ModifierUtils.CheckAccessibility(this.DeclarationModifiers, this, isExplicitInterfaceImplementation: false, diagnostics, location); if (!modifierErrors) { - this.CheckModifiers(methodKind, hasBody, location, diagnostics); + this.CheckModifiers(methodKind, hasAnyBody, location, diagnostics); } CheckForBlockAndExpressionBody( @@ -163,14 +164,6 @@ internal override OneOrMany> GetAttributeDeclara return OneOrMany.Create(((ConstructorDeclarationSyntax)this.SyntaxNode).AttributeLists); } - internal override bool IsExpressionBodied - { - get - { - return _isExpressionBodied; - } - } - internal override bool IsNullableAnalysisEnabled() { return _hasThisInitializer ? diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs index 431d62ece58b7..00e94036b411f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs @@ -18,7 +18,6 @@ internal abstract class SourceConstructorSymbolBase : SourceMemberMethodSymbol { protected ImmutableArray _lazyParameters; private TypeWithAnnotations _lazyReturnType; - private bool _lazyIsVararg; protected SourceConstructorSymbolBase( SourceMemberContainerTypeSymbol containingType, @@ -48,15 +47,13 @@ protected sealed override void MethodChecks(BindingDiagnosticBag diagnostics) // instance). Constraints are checked in AfterAddingTypeMembersChecks. var signatureBinder = bodyBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); - SyntaxToken arglistToken; _lazyParameters = ParameterHelpers.MakeParameters( - signatureBinder, this, parameterList, out arglistToken, + signatureBinder, this, parameterList, out _, allowRefOrOut: AllowRefOrOut, allowThis: false, addRefReadOnlyModifier: false, diagnostics: diagnostics).Cast(); - _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); _lazyReturnType = TypeWithAnnotations.Create(bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax)); var location = this.GetFirstLocation(); @@ -72,7 +69,7 @@ protected sealed override void MethodChecks(BindingDiagnosticBag diagnostics) this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics); this.CheckFileTypeUsage(_lazyReturnType, _lazyParameters, diagnostics); - if (_lazyIsVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams)) + if (this.IsVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams)) { diagnostics.Add(ErrorCode.ERR_BadVarargs, location); } @@ -100,15 +97,6 @@ internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conve } } - public sealed override bool IsVararg - { - get - { - LazyMethodChecks(); - return _lazyIsVararg; - } - } - public sealed override bool IsImplicitlyDeclared { get @@ -150,11 +138,6 @@ public sealed override ImmutableArray> GetTy public sealed override ImmutableArray GetTypeParameterConstraintKinds() => ImmutableArray.Empty; - public override RefKind RefKind - { - get { return RefKind.None; } - } - public sealed override TypeWithAnnotations ReturnTypeWithAnnotations { get diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs index 69ca26275e2ac..33b135319d643 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventAccessorSymbol.cs @@ -4,7 +4,6 @@ #nullable disable -using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Syntax; using Roslyn.Utilities; @@ -32,7 +31,9 @@ internal SourceCustomEventAccessorSymbol( syntax.Keyword.GetLocation(), explicitlyImplementedEventOpt, aliasQualifierOpt, isAdder: syntax.Kind() == SyntaxKind.AddAccessorDeclaration, isIterator: SyntaxFacts.HasYieldOperations(syntax.Body), - isNullableAnalysisEnabled: isNullableAnalysisEnabled) + isNullableAnalysisEnabled: isNullableAnalysisEnabled, + hasAnyBody: syntax.Body is not null || syntax.ExpressionBody is not null, + isExpressionBodied: syntax is { Body: null, ExpressionBody: not null }) { Debug.Assert(syntax != null); Debug.Assert(syntax.Kind() == SyntaxKind.AddAccessorDeclaration || syntax.Kind() == SyntaxKind.RemoveAccessorDeclaration); @@ -91,16 +92,5 @@ internal override bool GenerateDebugInfo { get { return true; } } - - internal override bool IsExpressionBodied - { - get - { - var syntax = GetSyntax(); - var hasBody = syntax.Body != null; - var hasExpressionBody = syntax.ExpressionBody != null; - return !hasBody && hasExpressionBody; - } - } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs index 44e86f087ab08..7f379c7072076 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceCustomEventSymbol.cs @@ -155,8 +155,9 @@ internal SourceCustomEventSymbol(SourceMemberContainerTypeSymbol containingType, diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, this.GetFirstLocation()); } - _addMethod = new SynthesizedEventAccessorSymbol(this, isAdder: true, explicitlyImplementedEvent, aliasQualifierOpt); - _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false, explicitlyImplementedEvent, aliasQualifierOpt); + // No body as this was an abstract event. + _addMethod = new SynthesizedEventAccessorSymbol(this, isAdder: true, hasAnyBody: false, isExpressionBodied: false, explicitlyImplementedEvent, aliasQualifierOpt); + _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false, hasAnyBody: false, isExpressionBodied: false, explicitlyImplementedEvent, aliasQualifierOpt); } else { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs index 28d792d0608a1..804ee3eea2b57 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs @@ -24,11 +24,14 @@ protected SourceDelegateMethodSymbol( TypeWithAnnotations returnType, DelegateDeclarationSyntax syntax, MethodKind methodKind, + RefKind refKind, DeclarationModifiers declarationModifiers) : base(delegateType, syntax.GetReference(), location: syntax.Identifier.GetLocation(), isIterator: false) { _returnType = returnType; - this.MakeFlags(methodKind, declarationModifiers, _returnType.IsVoidType(), isExtensionMethod: false, isNullableAnalysisEnabled: false); + this.MakeFlags( + methodKind, refKind, declarationModifiers, _returnType.IsVoidType(), hasAnyBody: false, isExpressionBodied: false, + isExtensionMethod: false, isVarArg: false, isNullableAnalysisEnabled: false); } internal sealed override ExecutableCodeBinder TryGetBodyBinder(BinderFactory binderFactoryOpt = null, bool ignoreAccessibility = false) => throw ExceptionUtilities.Unreachable(); @@ -129,14 +132,6 @@ protected override void MethodChecks(BindingDiagnosticBag diagnostics) // TODO: move more functionality into here, making these symbols more lazy } - public sealed override bool IsVararg - { - get - { - return false; - } - } - public sealed override ImmutableArray Parameters { get @@ -176,11 +171,6 @@ public sealed override bool IsImplicitlyDeclared } } - internal override bool IsExpressionBodied - { - get { return false; } - } - internal override bool GenerateDebugInfo { get { return false; } @@ -219,7 +209,7 @@ internal Constructor( TypeWithAnnotations objectType, TypeWithAnnotations intPtrType, DelegateDeclarationSyntax syntax) - : base(delegateType, voidType, syntax, MethodKind.Constructor, DeclarationModifiers.Public) + : base(delegateType, voidType, syntax, MethodKind.Constructor, RefKind.None, DeclarationModifiers.Public) { InitializeParameters(ImmutableArray.Create( SynthesizedParameterSymbol.Create(this, objectType, 0, RefKind.None, "object"), @@ -231,11 +221,6 @@ public override string Name get { return WellKnownMemberNames.InstanceConstructorName; } } - public override RefKind RefKind - { - get { return RefKind.None; } - } - internal override OneOrMany> GetReturnTypeAttributeDeclarations() { // Constructors don't have return type attributes @@ -258,7 +243,6 @@ internal override LexicalSortKey GetLexicalSortKey() private sealed class InvokeMethod : SourceDelegateMethodSymbol { - private readonly RefKind _refKind; private readonly ImmutableArray _refCustomModifiers; internal InvokeMethod( @@ -268,10 +252,8 @@ internal InvokeMethod( DelegateDeclarationSyntax syntax, Binder binder, BindingDiagnosticBag diagnostics) - : base(delegateType, returnType, syntax, MethodKind.DelegateInvoke, DeclarationModifiers.Virtual | DeclarationModifiers.Public) + : base(delegateType, returnType, syntax, MethodKind.DelegateInvoke, refKind, DeclarationModifiers.Virtual | DeclarationModifiers.Public) { - this._refKind = refKind; - SyntaxToken arglistToken; var parameters = ParameterHelpers.MakeParameters( binder, this, syntax.ParameterList, out arglistToken, @@ -288,7 +270,7 @@ internal InvokeMethod( diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken)); } - if (_refKind == RefKind.RefReadOnly) + if (this.RefKind == RefKind.RefReadOnly) { var modifierType = binder.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_InAttribute, diagnostics, syntax.ReturnType); _refCustomModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType)); @@ -306,11 +288,6 @@ public override string Name get { return WellKnownMemberNames.DelegateInvokeName; } } - public override RefKind RefKind - { - get { return _refKind; } - } - internal override LexicalSortKey GetLexicalSortKey() { // associate "Invoke and .ctor" with whole delegate declaration for the sorting purposes @@ -332,7 +309,7 @@ internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, base.AfterAddingTypeMembersChecks(conversions, diagnostics); - if (_refKind == RefKind.RefReadOnly) + if (this.RefKind == RefKind.RefReadOnly) { compilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: true); } @@ -367,7 +344,7 @@ internal BeginInvokeMethod( TypeWithAnnotations objectType, TypeWithAnnotations asyncCallbackType, DelegateDeclarationSyntax syntax) - : base((SourceNamedTypeSymbol)invoke.ContainingType, iAsyncResultType, syntax, MethodKind.Ordinary, DeclarationModifiers.Virtual | DeclarationModifiers.Public) + : base((SourceNamedTypeSymbol)invoke.ContainingType, iAsyncResultType, syntax, MethodKind.Ordinary, RefKind.None, DeclarationModifiers.Virtual | DeclarationModifiers.Public) { var parameters = ArrayBuilder.GetInstance(); foreach (SourceParameterSymbol p in invoke.Parameters) @@ -388,11 +365,6 @@ public override string Name get { return WellKnownMemberNames.DelegateBeginInvokeName; } } - public override RefKind RefKind - { - get { return RefKind.None; } - } - internal override OneOrMany> GetReturnTypeAttributeDeclarations() { // BeginInvoke method doesn't have return type attributes @@ -410,7 +382,7 @@ internal EndInvokeMethod( InvokeMethod invoke, TypeWithAnnotations iAsyncResultType, DelegateDeclarationSyntax syntax) - : base((SourceNamedTypeSymbol)invoke.ContainingType, invoke.ReturnTypeWithAnnotations, syntax, MethodKind.Ordinary, DeclarationModifiers.Virtual | DeclarationModifiers.Public) + : base((SourceNamedTypeSymbol)invoke.ContainingType, invoke.ReturnTypeWithAnnotations, syntax, MethodKind.Ordinary, invoke.RefKind, DeclarationModifiers.Virtual | DeclarationModifiers.Public) { _invoke = invoke; @@ -434,8 +406,6 @@ internal EndInvokeMethod( public override string Name => WellKnownMemberNames.DelegateEndInvokeName; - public override RefKind RefKind => _invoke.RefKind; - public override ImmutableArray RefCustomModifiers => _invoke.RefCustomModifiers; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDestructorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDestructorSymbol.cs index 26dc833d7353d..fe0457aee98d3 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceDestructorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceDestructorSymbol.cs @@ -14,7 +14,6 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols internal sealed class SourceDestructorSymbol : SourceMemberMethodSymbol { private TypeWithAnnotations _lazyReturnType; - private readonly bool _isExpressionBodied; internal SourceDestructorSymbol( SourceMemberContainerTypeSymbol containingType, @@ -28,17 +27,21 @@ internal SourceDestructorSymbol( bool modifierErrors; var declarationModifiers = MakeModifiers(syntax.Modifiers, location, diagnostics, out modifierErrors); - this.MakeFlags(methodKind, declarationModifiers, returnsVoid: true, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled); + + bool hasBlockBody = syntax.Body != null; + bool isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; + bool hasAnyBody = hasBlockBody || isExpressionBodied; + + this.MakeFlags( + methodKind, RefKind.None, declarationModifiers, returnsVoid: true, hasAnyBody: hasAnyBody, isExpressionBodied: isExpressionBodied, isExtensionMethod: false, + isVarArg: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled); if (syntax.Identifier.ValueText != containingType.Name) { diagnostics.Add(ErrorCode.ERR_BadDestructorName, syntax.Identifier.GetLocation()); } - bool hasBlockBody = syntax.Body != null; - _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; - - if (hasBlockBody || _isExpressionBodied) + if (hasBlockBody || isExpressionBodied) { if (IsExtern) { @@ -46,7 +49,7 @@ internal SourceDestructorSymbol( } } - if (!modifierErrors && !hasBlockBody && !_isExpressionBodied && !IsExtern) + if (!modifierErrors && !hasBlockBody && !isExpressionBodied && !IsExtern) { diagnostics.Add(ErrorCode.ERR_ConcreteMissingBody, location, this); } @@ -84,11 +87,6 @@ internal override ExecutableCodeBinder TryGetBodyBinder(BinderFactory binderFact return TryGetBodyBinderFromSyntax(binderFactoryOpt, ignoreAccessibility); } - public override bool IsVararg - { - get { return false; } - } - internal override int ParameterCount { get { return 0; } @@ -110,11 +108,6 @@ public override ImmutableArray> GetTypeParam public override ImmutableArray GetTypeParameterConstraintKinds() => ImmutableArray.Empty; - public override RefKind RefKind - { - get { return RefKind.None; } - } - public override TypeWithAnnotations ReturnTypeWithAnnotations { get @@ -142,14 +135,6 @@ public override string Name get { return WellKnownMemberNames.DestructorName; } } - internal override bool IsExpressionBodied - { - get - { - return _isExpressionBodied; - } - } - internal override OneOrMany> GetAttributeDeclarations() { // destructors can't have return type attributes diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs index dc99d2054c40d..c67ba98104cce 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventAccessorSymbol.cs @@ -29,7 +29,9 @@ public SourceEventAccessorSymbol( string aliasQualifierOpt, bool isAdder, bool isIterator, - bool isNullableAnalysisEnabled) + bool isNullableAnalysisEnabled, + bool hasAnyBody, + bool isExpressionBodied) : base(@event.containingType, syntaxReference, location, isIterator) { _event = @event; @@ -54,10 +56,14 @@ public SourceEventAccessorSymbol( this.MakeFlags( isAdder ? MethodKind.EventAdd : MethodKind.EventRemove, + RefKind.None, @event.Modifiers, returnsVoid: false, // until we learn otherwise (in LazyMethodChecks). + hasAnyBody: hasAnyBody, + isExpressionBodied: isExpressionBodied, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled, + isVarArg: false, isMetadataVirtualIgnoringModifiers: @event.IsExplicitInterfaceImplementation && (@event.Modifiers & DeclarationModifiers.Static) == 0); _name = GetOverriddenAccessorName(@event, isAdder) ?? name; @@ -163,11 +169,6 @@ public sealed override bool ReturnsVoid } } - public override RefKind RefKind - { - get { return RefKind.None; } - } - public sealed override TypeWithAnnotations ReturnTypeWithAnnotations { get @@ -196,11 +197,6 @@ public sealed override ImmutableArray Parameters } } - public sealed override bool IsVararg - { - get { return false; } - } - public sealed override ImmutableArray TypeParameters { get { return ImmutableArray.Empty; } @@ -246,11 +242,5 @@ protected string GetOverriddenAccessorName(SourceEventSymbol @event, bool isAdde return null; } - - internal override bool IsExpressionBodied - { - // Events cannot be expression-bodied - get { return false; } - } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs index 0998929b2dbad..0db8d93d0c41c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs @@ -113,9 +113,11 @@ internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingTy } } - // Accessors will assume that Type is available. - _addMethod = new SynthesizedEventAccessorSymbol(this, isAdder: true); - _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false); + // Accessors will assume that Type is available. We consider abstract/extern accessors to not have a + // body, but all others do have one. + var hasAnyBody = !IsAbstract && !IsExtern; + _addMethod = new SynthesizedEventAccessorSymbol(this, isAdder: true, hasAnyBody: hasAnyBody, isExpressionBodied: false); + _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false, hasAnyBody: hasAnyBody, isExpressionBodied: false); if (declarationSyntax.Variables[0] == declaratorSyntax) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index a6288faa15dd7..7cd2ddded6a85 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -24,9 +24,10 @@ protected struct Flags { // We currently pack everything into a 32 bit int with the following layout: // - // | |n|vvv|yy|s|r|q|z|wwwww| + // | |a|b|e|n|vvv|yy|s|r|q|z|kk|wwwww| // // w = method kind. 5 bits. + // k = ref kind. 2 bits. // z = isExtensionMethod. 1 bit. // q = isMetadataVirtualIgnoringInterfaceChanges. 1 bit. // r = isMetadataVirtual. 1 bit. (At least as true as isMetadataVirtualIgnoringInterfaceChanges.) @@ -34,12 +35,20 @@ protected struct Flags // y = ReturnsVoid. 2 bits. // v = NullableContext. 3 bits. // n = IsNullableAnalysisEnabled. 1 bit. + // e = IsExpressionBody. 1 bit. + // b = HasAnyBody. 1 bit. + // a = IsVararg. 1 bit private int _flags; private const int MethodKindOffset = 0; private const int MethodKindSize = 5; + private const int MethodKindMask = (1 << MethodKindSize) - 1; + + private const int RefKindOffset = MethodKindOffset + MethodKindSize; + private const int RefKindSize = 2; + private const int RefKindMask = (1 << RefKindSize) - 1; - private const int IsExtensionMethodOffset = MethodKindOffset + MethodKindSize; + private const int IsExtensionMethodOffset = RefKindOffset + RefKindSize; private const int IsExtensionMethodSize = 1; private const int IsMetadataVirtualIgnoringInterfaceChangesOffset = IsExtensionMethodOffset + IsExtensionMethodSize; @@ -56,24 +65,33 @@ protected struct Flags private const int NullableContextOffset = ReturnsVoidOffset + ReturnsVoidSize; private const int NullableContextSize = 3; + private const int NullableContextMask = (1 << NullableContextSize) - 1; private const int IsNullableAnalysisEnabledOffset = NullableContextOffset + NullableContextSize; -#pragma warning disable IDE0051 // Remove unused private members private const int IsNullableAnalysisEnabledSize = 1; -#pragma warning restore IDE0051 // Remove unused private members - private const int MethodKindMask = (1 << MethodKindSize) - 1; + private const int IsExpressionBodiedOffset = IsNullableAnalysisEnabledOffset + IsNullableAnalysisEnabledSize; + private const int IsExpressionBodiedSize = 1; + + private const int HasAnyBodyOffset = IsExpressionBodiedOffset + IsExpressionBodiedSize; + private const int HasAnyBodySize = 1; + private const int IsVarargOffset = HasAnyBodyOffset + HasAnyBodySize; +#pragma warning disable IDE0051 // Remove unused private members + private const int IsVarargSize = 1; +#pragma warning restore IDE0051 // Remove unused private members + + private const int HasAnyBodyBit = 1 << HasAnyBodyOffset; + private const int IsExpressionBodiedBit = 1 << IsExpressionBodiedOffset; private const int IsExtensionMethodBit = 1 << IsExtensionMethodOffset; private const int IsMetadataVirtualIgnoringInterfaceChangesBit = 1 << IsMetadataVirtualIgnoringInterfaceChangesOffset; private const int IsMetadataVirtualBit = 1 << IsMetadataVirtualIgnoringInterfaceChangesOffset; private const int IsMetadataVirtualLockedBit = 1 << IsMetadataVirtualLockedOffset; + private const int IsVarargBit = 1 << IsVarargOffset; private const int ReturnsVoidBit = 1 << ReturnsVoidOffset; private const int ReturnsVoidIsSetBit = 1 << ReturnsVoidOffset + 1; - private const int NullableContextMask = (1 << NullableContextSize) - 1; - private const int IsNullableAnalysisEnabledBit = 1 << IsNullableAnalysisEnabledOffset; public bool TryGetReturnsVoid(out bool value) @@ -93,6 +111,21 @@ public MethodKind MethodKind get { return (MethodKind)((_flags >> MethodKindOffset) & MethodKindMask); } } + public RefKind RefKind + { + get { return (RefKind)((_flags >> RefKindOffset) & RefKindMask); } + } + + public bool HasAnyBody + { + get { return (_flags & HasAnyBodyBit) != 0; } + } + + public bool IsExpressionBodied + { + get { return (_flags & IsExpressionBodiedBit) != 0; } + } + public bool IsExtensionMethod { get { return (_flags & IsExtensionMethodBit) != 0; } @@ -108,11 +141,17 @@ public bool IsMetadataVirtualLocked get { return (_flags & IsMetadataVirtualLockedBit) != 0; } } + public bool IsVararg + { + get { return (_flags & IsVarargBit) != 0; } + } + #if DEBUG static Flags() { // Verify masks are sufficient for values. Debug.Assert(EnumUtilities.ContainsAllValues(MethodKindMask)); + Debug.Assert(EnumUtilities.ContainsAllValues(RefKindMask)); Debug.Assert(EnumUtilities.ContainsAllValues(NullableContextMask)); } #endif @@ -124,23 +163,35 @@ private static bool ModifiersRequireMetadataVirtual(DeclarationModifiers modifie public Flags( MethodKind methodKind, + RefKind refKind, DeclarationModifiers declarationModifiers, bool returnsVoid, + bool hasAnyBody, + bool isExpressionBodied, bool isExtensionMethod, bool isNullableAnalysisEnabled, + bool isVararg, bool isMetadataVirtualIgnoringModifiers = false) { bool isMetadataVirtual = isMetadataVirtualIgnoringModifiers || ModifiersRequireMetadataVirtual(declarationModifiers); int methodKindInt = ((int)methodKind & MethodKindMask) << MethodKindOffset; + int refKindInt = ((int)refKind & RefKindMask) << RefKindOffset; + int hasAnyBodyInt = hasAnyBody ? HasAnyBodyBit : 0; + int isExpressionBodyInt = isExpressionBodied ? IsExpressionBodiedBit : 0; int isExtensionMethodInt = isExtensionMethod ? IsExtensionMethodBit : 0; int isNullableAnalysisEnabledInt = isNullableAnalysisEnabled ? IsNullableAnalysisEnabledBit : 0; + int isVarargInt = isVararg ? IsVarargBit : 0; int isMetadataVirtualIgnoringInterfaceImplementationChangesInt = isMetadataVirtual ? IsMetadataVirtualIgnoringInterfaceChangesBit : 0; int isMetadataVirtualInt = isMetadataVirtual ? IsMetadataVirtualBit : 0; _flags = methodKindInt + | refKindInt + | hasAnyBodyInt + | isExpressionBodyInt | isExtensionMethodInt | isNullableAnalysisEnabledInt + | isVarargInt | isMetadataVirtualIgnoringInterfaceImplementationChangesInt | isMetadataVirtualInt | (returnsVoid ? ReturnsVoidBit : 0) @@ -290,14 +341,18 @@ protected void CheckFileTypeUsage(TypeWithAnnotations returnType, ImmutableArray protected void MakeFlags( MethodKind methodKind, + RefKind refKind, DeclarationModifiers declarationModifiers, bool returnsVoid, + bool hasAnyBody, + bool isExpressionBodied, bool isExtensionMethod, bool isNullableAnalysisEnabled, + bool isVarArg, bool isMetadataVirtualIgnoringModifiers = false) { DeclarationModifiers = declarationModifiers; - this.flags = new Flags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isNullableAnalysisEnabled, isMetadataVirtualIgnoringModifiers); + this.flags = new Flags(methodKind, refKind, declarationModifiers, returnsVoid, hasAnyBody, isExpressionBodied, isExtensionMethod, isNullableAnalysisEnabled, isVarArg, isMetadataVirtualIgnoringModifiers); } protected void SetReturnsVoid(bool returnsVoid) @@ -1003,7 +1058,11 @@ protected void CheckFeatureAvailabilityAndRuntimeSupport(SyntaxNode declarationS /// If the method has both block body and an expression body /// present, this is not treated as expression-bodied. /// - internal abstract bool IsExpressionBodied { get; } + internal bool IsExpressionBodied => flags.IsExpressionBodied; + protected bool HasAnyBody => flags.HasAnyBody; + + public sealed override RefKind RefKind => this.flags.RefKind; + public sealed override bool IsVararg => this.flags.IsVararg; internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs index b619030b5f6ec..89d6fdf22a057 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs @@ -19,10 +19,6 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols internal sealed class SourceOrdinaryMethodSymbol : SourceOrdinaryMethodSymbolBase { private readonly TypeSymbol _explicitInterfaceType; - private readonly bool _isExpressionBodied; - private readonly bool _hasAnyBody; - private readonly RefKind _refKind; - private bool _lazyIsVararg; private readonly TypeParameterInfo _typeParameterInfo; @@ -68,13 +64,16 @@ private SourceOrdinaryMethodSymbol( location, syntax, methodKind, + refKind: syntax.ReturnType.SkipScoped(out _).GetRefKindInLocalOrReturn(diagnostics), isIterator: SyntaxFacts.HasYieldOperations(syntax.Body), isExtensionMethod: syntax.ParameterList.Parameters.FirstOrDefault() is ParameterSyntax firstParam && !firstParam.IsArgList && firstParam.Modifiers.Any(SyntaxKind.ThisKeyword), isReadOnly: false, - hasBody: syntax.Body != null || syntax.ExpressionBody != null, + hasAnyBody: syntax.Body != null || syntax.ExpressionBody != null, + isExpressionBodied: syntax is { Body: null, ExpressionBody: not null }, isNullableAnalysisEnabled: isNullableAnalysisEnabled, + isVarArg: syntax.ParameterList.Parameters.Any(p => p.IsArgList), diagnostics) { Debug.Assert(diagnostics.DiagnosticBag is object); @@ -88,12 +87,7 @@ private SourceOrdinaryMethodSymbol( _explicitInterfaceType = explicitInterfaceType; - bool hasBlockBody = syntax.Body != null; - _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; - bool hasBody = hasBlockBody || _isExpressionBodied; - _hasAnyBody = hasBody; Debug.Assert(syntax.ReturnType is not ScopedTypeSyntax); - _refKind = syntax.ReturnType.SkipScoped(out _).GetRefKindInLocalOrReturn(diagnostics); CheckForBlockAndExpressionBody( syntax.Body, syntax.ExpressionBody, syntax, diagnostics); @@ -108,13 +102,11 @@ public override ImmutableArray TypeParameters } } - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var syntax = GetSyntax(); var withTypeParamsBinder = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree).GetBinder(syntax.ReturnType, syntax, this); - 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 @@ -123,13 +115,12 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray parameters = ParameterHelpers.MakeParameters( - signatureBinder, this, syntax.ParameterList, out arglistToken, + signatureBinder, this, syntax.ParameterList, out _, allowRefOrOut: true, allowThis: true, addRefReadOnlyModifier: IsVirtual || IsAbstract, diagnostics: diagnostics).Cast(); - _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); var returnTypeSyntax = syntax.ReturnType; Debug.Assert(returnTypeSyntax is not ScopedTypeSyntax); @@ -183,7 +174,7 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray declaredConstraints) { @@ -274,8 +265,6 @@ protected override MethodSymbol FindExplicitlyImplementedMethod(BindingDiagnosti protected override TypeSymbol ExplicitInterfaceType => _explicitInterfaceType; - protected override bool HasAnyBody => _hasAnyBody; - internal MethodDeclarationSyntax GetSyntax() { Debug.Assert(syntaxReferenceOpt != null); @@ -348,25 +337,8 @@ public override ImmutableArray GetTypeParameterCons return _typeParameterInfo.LazyTypeParameterConstraintKinds; } - public override bool IsVararg - { - get - { - LazyMethodChecks(); - return _lazyIsVararg; - } - } - protected override int GetParameterCountFromSyntax() => GetSyntax().ParameterList.ParameterCount; - public override RefKind RefKind - { - get - { - return _refKind; - } - } - internal static void InitializePartialMethodParts(SourceOrdinaryMethodSymbol definition, SourceOrdinaryMethodSymbol implementation) { Debug.Assert(definition.IsPartialDefinition); @@ -393,7 +365,7 @@ internal bool IsPartialDefinition { get { - return this.IsPartial && !_hasAnyBody && !HasExternModifier; + return this.IsPartial && !HasAnyBody && !HasExternModifier; } } @@ -404,7 +376,7 @@ internal bool IsPartialImplementation { get { - return this.IsPartial && (_hasAnyBody || HasExternModifier); + return this.IsPartial && (HasAnyBody || HasExternModifier); } } @@ -509,11 +481,6 @@ private SyntaxList AttributeDeclarationSyntaxList } } - internal override bool IsExpressionBodied - { - get { return _isExpressionBodied; } - } - protected override DeclarationModifiers MakeDeclarationModifiers(DeclarationModifiers allowedModifiers, BindingDiagnosticBag diagnostics) { var syntax = GetSyntax(); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs index 2eaef04464ab7..28184ed27f878 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs @@ -31,11 +31,14 @@ protected SourceOrdinaryMethodSymbolBase( Location location, CSharpSyntaxNode syntax, MethodKind methodKind, + RefKind refKind, bool isIterator, bool isExtensionMethod, bool isReadOnly, - bool hasBody, + bool hasAnyBody, + bool isExpressionBodied, bool isNullableAnalysisEnabled, + bool isVarArg, BindingDiagnosticBag diagnostics) : base(containingType, syntax.GetReference(), @@ -53,17 +56,20 @@ protected SourceOrdinaryMethodSymbolBase( const bool returnsVoid = false; DeclarationModifiers declarationModifiers; - (declarationModifiers, HasExplicitAccessModifier) = this.MakeModifiers(methodKind, isReadOnly, hasBody, location, diagnostics); + (declarationModifiers, HasExplicitAccessModifier) = this.MakeModifiers(methodKind, isReadOnly, hasAnyBody, location, diagnostics); //explicit impls must be marked metadata virtual unless static bool isExplicitInterfaceImplementation = methodKind == MethodKind.ExplicitInterfaceImplementation; var isMetadataVirtualIgnoringModifiers = isExplicitInterfaceImplementation && (declarationModifiers & DeclarationModifiers.Static) == 0; - this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod: isExtensionMethod, isNullableAnalysisEnabled: isNullableAnalysisEnabled, isMetadataVirtualIgnoringModifiers: isMetadataVirtualIgnoringModifiers); + this.MakeFlags( + methodKind, refKind, declarationModifiers, returnsVoid, hasAnyBody: hasAnyBody, isExpressionBodied: isExpressionBodied, + isExtensionMethod: isExtensionMethod, isNullableAnalysisEnabled: isNullableAnalysisEnabled, isVarArg: isVarArg, + isMetadataVirtualIgnoringModifiers: isMetadataVirtualIgnoringModifiers); - CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasBody, diagnostics); + CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasAnyBody, diagnostics); - if (hasBody) + if (hasAnyBody) { CheckModifiersForBody(location, diagnostics); } @@ -76,7 +82,7 @@ protected override void MethodChecks(BindingDiagnosticBag diagnostics) { Debug.Assert(this.MethodKind != MethodKind.UserDefinedOperator, "SourceUserDefinedOperatorSymbolBase overrides this"); - var (returnType, parameters, isVararg, declaredConstraints) = MakeParametersAndBindReturnType(diagnostics); + var (returnType, parameters, declaredConstraints) = MakeParametersAndBindReturnType(diagnostics); MethodSymbol? overriddenOrExplicitlyImplementedMethod = MethodChecks(returnType, parameters, diagnostics); @@ -119,13 +125,11 @@ protected override void MethodChecks(BindingDiagnosticBag diagnostics) } } - CheckModifiers(MethodKind == MethodKind.ExplicitInterfaceImplementation, isVararg, HasAnyBody, _location, diagnostics); + CheckModifiers(MethodKind == MethodKind.ExplicitInterfaceImplementation, HasAnyBody, _location, diagnostics); } #nullable disable - protected abstract (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics); - - protected abstract bool HasAnyBody { get; } + protected abstract (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics); protected sealed override void LazyAsyncMethodChecks(CancellationToken cancellationToken) { @@ -300,8 +304,10 @@ private static DeclarationModifiers AddImpliedModifiers(DeclarationModifiers mod internal bool HasExtendedPartialModifier => (DeclarationModifiers & PartialMethodExtendedModifierMask) != 0; - private void CheckModifiers(bool isExplicitInterfaceImplementation, bool isVararg, bool hasBody, Location location, BindingDiagnosticBag diagnostics) + private void CheckModifiers(bool isExplicitInterfaceImplementation, bool hasBody, Location location, BindingDiagnosticBag diagnostics) { + bool isVararg = this.IsVararg; + Debug.Assert(!IsStatic || !IsOverride); // Otherwise should have been reported and cleared earlier. Debug.Assert(!IsStatic || ContainingType.IsInterface || (!IsAbstract && !IsVirtual)); // Otherwise should have been reported and cleared earlier. diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs index c1c7d572ce5d5..634f427a7a537 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs @@ -23,7 +23,6 @@ internal class SourcePropertyAccessorSymbol : SourceMemberMethodSymbol private ImmutableArray _lazyExplicitInterfaceImplementations; private string _lazyName; private readonly bool _isAutoPropertyAccessor; - private readonly bool _isExpressionBodied; private readonly bool _usesInit; public static SourcePropertyAccessorSymbol CreateAccessorSymbol( @@ -99,7 +98,7 @@ public static SourcePropertyAccessorSymbol CreateAccessorSymbol( propertyModifiers, location, syntax, - hasBody: false, + hasBlockBody: false, hasExpressionBody: false, isIterator: false, modifiers: default, @@ -128,9 +127,6 @@ public static SourcePropertyAccessorSymbol CreateAccessorSymbol( } #nullable disable - internal sealed override bool IsExpressionBodied - => _isExpressionBodied; - internal sealed override ImmutableArray NotNullMembers => _property.NotNullMembers.Concat(base.NotNullMembers); @@ -152,7 +148,6 @@ private SourcePropertyAccessorSymbol( { _property = property; _isAutoPropertyAccessor = false; - _isExpressionBodied = true; // The modifiers for the accessor are the same as the modifiers for the property, // minus the indexer and readonly bit @@ -161,8 +156,8 @@ private SourcePropertyAccessorSymbol( // ReturnsVoid property is overridden in this class so // returnsVoid argument to MakeFlags is ignored. bool isExplicitInterfaceImplementation = property.IsExplicitInterfaceImplementation; - this.MakeFlags(MethodKind.PropertyGet, declarationModifiers, returnsVoid: false, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled, - isMetadataVirtualIgnoringModifiers: isExplicitInterfaceImplementation && (declarationModifiers & DeclarationModifiers.Static) == 0); + this.MakeFlags(MethodKind.PropertyGet, _property.RefKind, declarationModifiers, returnsVoid: false, hasAnyBody: true, isExpressionBodied: true, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled, + isVarArg: false, isMetadataVirtualIgnoringModifiers: isExplicitInterfaceImplementation && (declarationModifiers & DeclarationModifiers.Static) == 0); CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasBody: true, diagnostics: diagnostics); CheckModifiersForBody(location, diagnostics); @@ -179,7 +174,7 @@ protected SourcePropertyAccessorSymbol( DeclarationModifiers propertyModifiers, Location location, CSharpSyntaxNode syntax, - bool hasBody, + bool hasBlockBody, bool hasExpressionBody, bool isIterator, SyntaxTokenList modifiers, @@ -196,7 +191,8 @@ protected SourcePropertyAccessorSymbol( _property = property; _isAutoPropertyAccessor = isAutoPropertyAccessor; Debug.Assert(!_property.IsExpressionBodied, "Cannot have accessors in expression bodied lightweight properties"); - _isExpressionBodied = !hasBody && hasExpressionBody; + var isExpressionBodied = !hasBlockBody && hasExpressionBody; + var hasAnyBody = hasBlockBody || hasExpressionBody; _usesInit = usesInit; if (_usesInit) { @@ -205,7 +201,7 @@ protected SourcePropertyAccessorSymbol( bool modifierErrors; bool isExplicitInterfaceImplementation = property.IsExplicitInterfaceImplementation; - var declarationModifiers = this.MakeModifiers(modifiers, isExplicitInterfaceImplementation, hasBody || hasExpressionBody, location, diagnostics, out modifierErrors); + var declarationModifiers = this.MakeModifiers(modifiers, isExplicitInterfaceImplementation, hasAnyBody, location, diagnostics, out modifierErrors); // Include some modifiers from the containing property, but not the accessibility modifiers. declarationModifiers |= GetAccessorModifiers(propertyModifiers) & ~DeclarationModifiers.AccessibilityMask; @@ -217,12 +213,12 @@ protected SourcePropertyAccessorSymbol( // ReturnsVoid property is overridden in this class so // returnsVoid argument to MakeFlags is ignored. - this.MakeFlags(methodKind, declarationModifiers, returnsVoid: false, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled, - isMetadataVirtualIgnoringModifiers: isExplicitInterfaceImplementation && (declarationModifiers & DeclarationModifiers.Static) == 0); + this.MakeFlags(methodKind, _property.RefKind, declarationModifiers, returnsVoid: false, hasAnyBody: hasAnyBody, isExpressionBodied: isExpressionBodied, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled, + isVarArg: false, isMetadataVirtualIgnoringModifiers: isExplicitInterfaceImplementation && (declarationModifiers & DeclarationModifiers.Static) == 0); - CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasBody: hasBody || hasExpressionBody || isAutoPropertyAccessor, diagnostics); + CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasBody: hasAnyBody || isAutoPropertyAccessor, diagnostics); - if (hasBody || hasExpressionBody) + if (hasAnyBody) { CheckModifiersForBody(location, diagnostics); } @@ -231,7 +227,7 @@ protected SourcePropertyAccessorSymbol( if (!modifierErrors) { - this.CheckModifiers(location, hasBody || hasExpressionBody, isAutoPropertyAccessor, diagnostics); + this.CheckModifiers(location, hasAnyBody, isAutoPropertyAccessor, diagnostics); } if (modifiers.Count > 0) @@ -308,11 +304,6 @@ public sealed override Symbol AssociatedSymbol get { return _property; } } - public sealed override bool IsVararg - { - get { return false; } - } - public sealed override bool ReturnsVoid { get { return this.ReturnType.IsVoidType(); } @@ -338,11 +329,6 @@ public sealed override ImmutableArray> GetTy public sealed override ImmutableArray GetTypeParameterConstraintKinds() => ImmutableArray.Empty; - public sealed override RefKind RefKind - { - get { return _property.RefKind; } - } - public sealed override TypeWithAnnotations ReturnTypeWithAnnotations { get diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedConversionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedConversionSymbol.cs index 0e9bac249c720..8d891bdcfe1af 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedConversionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedConversionSymbol.cs @@ -67,7 +67,7 @@ private SourceUserDefinedConversionSymbol( location, syntax, MakeDeclarationModifiers(methodKind, containingType.IsInterface, syntax, location, diagnostics), - hasBody: syntax.HasAnyBody(), + hasAnyBody: syntax.HasAnyBody(), isExpressionBodied: syntax.Body == null && syntax.ExpressionBody != null, isIterator: SyntaxFacts.HasYieldOperations(syntax.Body), isNullableAnalysisEnabled: isNullableAnalysisEnabled, diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbol.cs index 4a9c89330c33f..647fcc7f676ef 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbol.cs @@ -72,7 +72,7 @@ private SourceUserDefinedOperatorSymbol( location, syntax, MakeDeclarationModifiers(methodKind, containingType.IsInterface, syntax, location, diagnostics), - hasBody: syntax.HasAnyBody(), + hasAnyBody: syntax.HasAnyBody(), isExpressionBodied: syntax.Body == null && syntax.ExpressionBody != null, isIterator: SyntaxFacts.HasYieldOperations(syntax.Body), isNullableAnalysisEnabled: isNullableAnalysisEnabled, diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs index 973254524cca1..a13bf13ecb34b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs @@ -17,7 +17,6 @@ internal abstract class SourceUserDefinedOperatorSymbolBase : SourceOrdinaryMeth // tomat: ignoreDynamic should be true, but we don't want to introduce breaking change. See bug 605326. private const TypeCompareKind ComparisonForUserDefinedOperators = TypeCompareKind.IgnoreTupleNames | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes; private readonly string _name; - private readonly bool _isExpressionBodied; #nullable enable private readonly TypeSymbol? _explicitInterfaceType; #nullable disable @@ -30,7 +29,7 @@ protected SourceUserDefinedOperatorSymbolBase( Location location, CSharpSyntaxNode syntax, DeclarationModifiers declarationModifiers, - bool hasBody, + bool hasAnyBody, bool isExpressionBodied, bool isIterator, bool isNullableAnalysisEnabled, @@ -39,7 +38,6 @@ protected SourceUserDefinedOperatorSymbolBase( { _explicitInterfaceType = explicitInterfaceType; _name = name; - _isExpressionBodied = isExpressionBodied; this.CheckUnsafeModifier(declarationModifiers, diagnostics); @@ -47,7 +45,9 @@ protected SourceUserDefinedOperatorSymbolBase( // assume that the return type is non-void; when we do the lazy initialization // of the parameters and return type we will update the flag if necessary. - this.MakeFlags(methodKind, declarationModifiers, returnsVoid: false, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled); + this.MakeFlags( + methodKind, RefKind.None, declarationModifiers, returnsVoid: false, hasAnyBody: hasAnyBody, isExpressionBodied: isExpressionBodied, + isExtensionMethod: false, isVarArg: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled); if (this.ContainingType.IsInterface && !(IsAbstract || IsVirtual) && !IsExplicitInterfaceImplementation && @@ -94,7 +94,7 @@ protected SourceUserDefinedOperatorSymbolBase( { diagnostics.Add(ErrorCode.ERR_AbstractNotVirtual, location, this.Kind.Localize(), this); } - else if (hasBody && (IsExtern || IsAbstract)) + else if (hasAnyBody && (IsExtern || IsAbstract)) { Debug.Assert(!(IsAbstract && IsExtern)); if (IsExtern) @@ -106,7 +106,7 @@ protected SourceUserDefinedOperatorSymbolBase( diagnostics.Add(ErrorCode.ERR_AbstractHasBody, location, this); } } - else if (!hasBody && !IsExtern && !IsAbstract && !IsPartial) + else if (!hasAnyBody && !IsExtern && !IsAbstract && !IsPartial) { // Do not report that the body is missing if the operator is marked as // partial or abstract; we will already have given an error for that so @@ -763,14 +763,6 @@ public sealed override string Name } } - public sealed override bool IsVararg - { - get - { - return false; - } - } - public sealed override bool IsExtensionMethod { get @@ -790,16 +782,6 @@ public sealed override ImmutableArray> GetTy public sealed override ImmutableArray GetTypeParameterConstraintKinds() => ImmutableArray.Empty; - public sealed override RefKind RefKind - { - get { return RefKind.None; } - } - - internal sealed override bool IsExpressionBodied - { - get { return _isExpressionBodied; } - } - protected sealed override void CheckConstraintsForExplicitInterfaceType(ConversionsBase conversions, BindingDiagnosticBag diagnostics) { if ((object)_explicitInterfaceType != null) diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructor.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructor.cs index 2703847c97b27..eb4f79ecf69a2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructor.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructor.cs @@ -25,12 +25,19 @@ public SynthesizedPrimaryConstructor( Debug.Assert(containingType.HasPrimaryConstructor); Debug.Assert(containingType is SourceNamedTypeSymbol); Debug.Assert(containingType is IAttributeTargetSymbol); + Debug.Assert(syntax.ParameterList != null); this.MakeFlags( MethodKind.Constructor, + RefKind.None, containingType.IsAbstract ? DeclarationModifiers.Protected : DeclarationModifiers.Public, returnsVoid: true, + // We consider synthesized constructors to have a body, since they effectively span the entire type, and + // can do things like create constructor assignments that write into the fields/props of the type. + hasAnyBody: true, + isExpressionBodied: false, isExtensionMethod: false, + isVarArg: syntax.ParameterList.Parameters.Any(static p => p.IsArgList), isNullableAnalysisEnabled: false); // IsNullableAnalysisEnabled uses containing type instead. } @@ -69,8 +76,6 @@ protected override ParameterListSyntax GetParameterList() protected override bool AllowRefOrOut => !(ContainingType is { IsRecord: true } or { IsRecordStruct: true }); - internal override bool IsExpressionBodied => false; - internal override bool IsNullableAnalysisEnabled() { return ContainingType.IsNullableEnabledForConstructorsAndInitializers(IsStatic); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs index bfcd9b9a62aa5..ed73aa912dd53 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs @@ -29,7 +29,7 @@ protected override DeclarationModifiers MakeDeclarationModifiers(DeclarationModi return result; } - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; var location = ReturnTypeLocation; @@ -38,7 +38,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs index c59a619a611d3..af74e3e402f7e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs @@ -95,13 +95,12 @@ static bool modifiersAreValid(DeclarationModifiers modifiers) return null; } - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { return (ReturnType: !ContainingAssembly.RuntimeSupportsCovariantReturnsOfClasses && VirtualCloneInBase() is { } baseClone ? baseClone.ReturnTypeWithAnnotations : TypeWithAnnotations.Create(isNullableEnabled: true, ContainingType), Parameters: ImmutableArray.Empty, - IsVararg: false, DeclaredConstraintsForOverrideOrImplementation: ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs index 6610ac14985f0..e542fe47fc9fc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs @@ -35,7 +35,7 @@ protected override DeclarationModifiers MakeDeclarationModifiers(DeclarationModi return result; } - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; var location = ReturnTypeLocation; @@ -50,7 +50,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs index b2c452ed7382c..0ac9cd56a77fe 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs @@ -137,7 +137,7 @@ internal GetAccessorSymbol( propertyModifiers, location, syntax, - hasBody: true, + hasBlockBody: true, hasExpressionBody: false, isIterator: false, modifiers: default, diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs index af2b12f8d6e80..e56734b5105b4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs @@ -37,7 +37,7 @@ internal abstract class SynthesizedRecordEqualityOperatorBase : SourceUserDefine protected SynthesizedRecordEqualityOperatorBase(SourceMemberContainerTypeSymbol containingType, string name, int memberOffset, BindingDiagnosticBag diagnostics) : base(MethodKind.UserDefinedOperator, explicitInterfaceType: null, name, containingType, containingType.GetFirstLocation(), (CSharpSyntaxNode)containingType.SyntaxReferences[0].GetSyntax(), - DeclarationModifiers.Public | DeclarationModifiers.Static, hasBody: true, isExpressionBodied: false, isIterator: false, isNullableAnalysisEnabled: false, diagnostics) + DeclarationModifiers.Public | DeclarationModifiers.Static, hasAnyBody: true, isExpressionBodied: false, isIterator: false, isNullableAnalysisEnabled: false, diagnostics) { Debug.Assert(name == WellKnownMemberNames.EqualityOperatorName || name == WellKnownMemberNames.InequalityOperatorName); _memberOffset = memberOffset; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs index ef03c9a21b5f1..c0049393fec9c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs @@ -32,7 +32,7 @@ protected override DeclarationModifiers MakeDeclarationModifiers(DeclarationModi return result; } - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; @@ -43,7 +43,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordGetHashCode.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordGetHashCode.cs index 183930cc2411f..f9ea532a468ae 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordGetHashCode.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordGetHashCode.cs @@ -26,14 +26,13 @@ public SynthesizedRecordGetHashCode(SourceMemberContainerTypeSymbol containingTy protected override SpecialMember OverriddenSpecialMember => SpecialMember.System_Object__GetHashCode; - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; var location = ReturnTypeLocation; return (ReturnType: TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_Int32, location, diagnostics)), Parameters: ImmutableArray.Empty, - IsVararg: false, DeclaredConstraintsForOverrideOrImplementation: ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs index e3779ce65dc53..e944deede9a62 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs @@ -23,7 +23,7 @@ public SynthesizedRecordObjEquals(SourceMemberContainerTypeSymbol containingType protected override SpecialMember OverriddenSpecialMember => SpecialMember.System_Object__Equals; - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; @@ -34,7 +34,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs index f063d89aa6ca9..0306e1c830606 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs @@ -21,16 +21,12 @@ internal abstract class SynthesizedRecordOrdinaryMethod : SourceOrdinaryMethodSy private readonly int _memberOffset; protected SynthesizedRecordOrdinaryMethod(SourceMemberContainerTypeSymbol containingType, string name, bool isReadOnly, bool hasBody, int memberOffset, BindingDiagnosticBag diagnostics) - : base(containingType, name, containingType.GetFirstLocation(), (CSharpSyntaxNode)containingType.SyntaxReferences[0].GetSyntax(), MethodKind.Ordinary, - isIterator: false, isExtensionMethod: false, isReadOnly: isReadOnly, hasBody: hasBody, isNullableAnalysisEnabled: false, diagnostics) + : base(containingType, name, containingType.GetFirstLocation(), (CSharpSyntaxNode)containingType.SyntaxReferences[0].GetSyntax(), MethodKind.Ordinary, RefKind.None, + isIterator: false, isExtensionMethod: false, isReadOnly: isReadOnly, hasAnyBody: hasBody, isExpressionBodied: false, isNullableAnalysisEnabled: false, isVarArg: false, diagnostics) { _memberOffset = memberOffset; } - protected sealed override bool HasAnyBody => true; - - internal sealed override bool IsExpressionBodied => false; - public sealed override bool IsImplicitlyDeclared => true; protected sealed override Location ReturnTypeLocation => GetFirstLocation(); @@ -78,10 +74,6 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r public sealed override string? GetDocumentationCommentXml(CultureInfo? preferredCulture = null, bool expandIncludes = false, CancellationToken cancellationToken = default) => null; - public sealed override bool IsVararg => false; - - public sealed override RefKind RefKind => RefKind.None; - internal sealed override bool GenerateDebugInfo => false; internal sealed override bool SynthesizesLoweredBoundBody => true; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs index 9129525d2f92f..3781497a6ec4a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs @@ -85,7 +85,7 @@ bool modifiersAreValid(DeclarationModifiers modifiers) #endif } - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; var location = ReturnTypeLocation; @@ -95,7 +95,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordToString.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordToString.cs index f66a3a786f0ef..33220633ece8a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordToString.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordToString.cs @@ -36,14 +36,13 @@ public SynthesizedRecordToString(SourceMemberContainerTypeSymbol containingType, protected override SpecialMember OverriddenSpecialMember => SpecialMember.System_Object__ToString; - protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) + protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { var compilation = DeclaringCompilation; var location = ReturnTypeLocation; var annotation = ContainingType.IsRecordStruct ? NullableAnnotation.Oblivious : NullableAnnotation.NotAnnotated; return (ReturnType: TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_String, location, diagnostics), annotation), Parameters: ImmutableArray.Empty, - IsVararg: false, DeclaredConstraintsForOverrideOrImplementation: ImmutableArray.Empty); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs index e165c6b2f3da6..5c133e454d8d1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs @@ -24,8 +24,8 @@ internal sealed class SynthesizedEventAccessorSymbol : SourceEventAccessorSymbol // Since we don't have a syntax reference, we'll have to use another object for locking. private readonly object _methodChecksLockObject = new object(); - internal SynthesizedEventAccessorSymbol(SourceEventSymbol @event, bool isAdder, EventSymbol explicitlyImplementedEventOpt = null, string aliasQualifierOpt = null) - : base(@event, null, @event.Location, explicitlyImplementedEventOpt, aliasQualifierOpt, isAdder, isIterator: false, isNullableAnalysisEnabled: false) + internal SynthesizedEventAccessorSymbol(SourceEventSymbol @event, bool isAdder, bool hasAnyBody, bool isExpressionBodied, EventSymbol explicitlyImplementedEventOpt = null, string aliasQualifierOpt = null) + : base(@event, null, @event.Location, explicitlyImplementedEventOpt, aliasQualifierOpt, isAdder, isIterator: false, isNullableAnalysisEnabled: false, hasAnyBody: hasAnyBody, isExpressionBodied: isExpressionBodied) { } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs index 232f54a690883..e102925092460 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs @@ -55,10 +55,15 @@ internal SynthesizedSimpleProgramEntryPointSymbol(SourceMemberContainerTypeSymbo bool isNullableAnalysisEnabled = IsNullableAnalysisEnabled(compilation, CompilationUnit); this.MakeFlags( MethodKind.Ordinary, + RefKind.None, DeclarationModifiers.Static | DeclarationModifiers.Private | (hasAwait ? DeclarationModifiers.Async : DeclarationModifiers.None), returnsVoid: !hasAwait && !hasReturnWithExpression, + // Consider the synthesized entrypoint to always have a body (conceptually the top level statements). + hasAnyBody: true, + isExpressionBodied: false, isExtensionMethod: false, isNullableAnalysisEnabled: isNullableAnalysisEnabled, + isVarArg: false, isMetadataVirtualIgnoringModifiers: false); _parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this, @@ -111,14 +116,6 @@ internal override System.Reflection.MethodImplAttributes ImplementationAttribute get { return default(System.Reflection.MethodImplAttributes); } } - public override bool IsVararg - { - get - { - return false; - } - } - public override ImmutableArray TypeParameters { get @@ -143,14 +140,6 @@ public override ImmutableArray Parameters } } - public override RefKind RefKind - { - get - { - return RefKind.None; - } - } - public override TypeWithAnnotations ReturnTypeWithAnnotations { get @@ -198,8 +187,6 @@ protected override void MethodChecks(BindingDiagnosticBag diagnostics) { } - internal override bool IsExpressionBodied => false; - public override ImmutableArray> GetTypeParameterConstraintTypes() => ImmutableArray>.Empty;