From c3daaae95b15b25084083dddc3ec16850386a40f Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Tue, 26 Feb 2019 13:23:48 -0800 Subject: [PATCH] Allow readonly modifier on property decls in general. Add more tests. --- .../Symbols/Source/SourcePropertySymbol.cs | 10 --- .../Semantics/ReadOnlyStructsTests.cs | 62 ++++++++++++++++--- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs index f2169f1457c99..033e0bfda6d28 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs @@ -115,11 +115,6 @@ private SourcePropertySymbol( : ((IndexerDeclarationSyntax)syntax).ExpressionBody; bool hasExpressionBody = arrowExpression != null; - if (!hasExpressionBody && HasReadOnlyModifier) - { - diagnostics.Add(ErrorCode.ERR_BadMemberFlag, location, SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword)); - } - bool hasInitializer = !isIndexer && propertySyntax.Initializer != null; bool notRegularProperty = (!IsAbstract && !IsExtern && !isIndexer && hasAccessorList); @@ -633,11 +628,6 @@ internal bool IsNew get { return (_modifiers & DeclarationModifiers.New) != 0; } } - private bool HasReadOnlyModifier - { - get { return (_modifiers & DeclarationModifiers.ReadOnly) != 0; } - } - public override MethodSymbol GetMethod { get { return _getMethod; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs index df424c947c140..d5d6bc0b60dbb 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs @@ -420,10 +420,7 @@ public struct S } "; var comp = CreateCompilation(csharp); - comp.VerifyDiagnostics( - // (5,25): error CS0106: The modifier 'readonly' is not valid for this item - // public readonly int P { get { return i; } } - Diagnostic(ErrorCode.ERR_BadMemberFlag, "P").WithArguments("readonly").WithLocation(5, 25)); + comp.VerifyDiagnostics(); } [Fact] @@ -433,8 +430,10 @@ public void ReadOnlyAutoProperty() public struct S { public int P1 { readonly get; } - public int P2 { readonly get; set; } - public int P3 { readonly get; readonly set; } // PROTOTYPE: readonly set on an auto-property should give an error + public readonly int P2 { get; } + public int P3 { readonly get; set; } + public int P4 { readonly get; readonly set; } // PROTOTYPE: readonly set on an auto-property should give an error + public readonly int P5 { get; set; } // PROTOTYPE: readonly set on an auto-property should give an error } "; var comp = CreateCompilation(csharp); @@ -453,7 +452,7 @@ public struct S public readonly ref int M1() => ref f1; private static readonly int f2; - public readonly ref readonly int M2() => ref f1; + public readonly ref readonly int M2() => ref f2; private static readonly int f3; public ref readonly int M3() @@ -466,5 +465,54 @@ public ref readonly int M3() var comp = CreateCompilation(csharp); comp.VerifyDiagnostics(); } + + [Fact] + public void ReadOnlyConstructor() + { + var csharp = @" +public struct S +{ + public readonly S(int i) { } +} +"; + var comp = CreateCompilation(csharp); + comp.VerifyDiagnostics( + // (4,21): error CS0106: The modifier 'readonly' is not valid for this item + // public readonly S(int i) { } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "S").WithArguments("readonly").WithLocation(4, 21)); + } + + [Fact] + public void ReadOnlyOperator() + { + var csharp = @" +public struct S +{ + public static readonly S operator +(S lhs, S rhs) => lhs; + public static readonly explicit operator int(S s) => 42; +} +"; + var comp = CreateCompilation(csharp); + comp.VerifyDiagnostics( + // (4,39): error CS0106: The modifier 'readonly' is not valid for this item + // public static readonly S operator +(S lhs, S rhs) => lhs; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "+").WithArguments("readonly").WithLocation(4, 39), + // (5,46): error CS0106: The modifier 'readonly' is not valid for this item + // public static readonly explicit operator int(S s) => 42; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "int").WithArguments("readonly").WithLocation(5, 46)); + } + + [Fact] + public void ReadOnlyDelegate() + { + var csharp = @" +public readonly delegate int Del(); +"; + var comp = CreateCompilation(csharp); + comp.VerifyDiagnostics( + // (2,30): error CS0106: The modifier 'readonly' is not valid for this item + // public readonly delegate int Del(); + Diagnostic(ErrorCode.ERR_BadMemberFlag, "Del").WithArguments("readonly").WithLocation(2, 30)); + } } }