From 7cce7803bbbaccf7b4b6b64e02635505e42f1ce0 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 22 Apr 2020 17:06:41 -0700 Subject: [PATCH] Address remaining feedback --- .../Portable/Binder/Binder.ValueChecks.cs | 3 +- .../Symbols/Wrapped/WrappedMethodSymbol.cs | 2 +- .../Semantic/Semantics/InitOnlyMemberTests.cs | 63 ++++++++++++++++++- .../MetadataReader/MetadataDecoder.cs | 1 + .../Symbols/Metadata/PE/SymbolFactory.vb | 2 +- 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index 26043c81a6ca1..94a08e8f123c3 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -756,8 +756,7 @@ bool isAssignedFromInitOnlySetterOnThis(BoundExpression receiver) return false; } - var containingMember = ContainingMemberOrLambda; - if (!(containingMember is MethodSymbol method)) + if (!(ContainingMemberOrLambda is MethodSymbol method)) { return false; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedMethodSymbol.cs index 64b723146f2ff..abdeb67724e00 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedMethodSymbol.cs @@ -349,6 +349,6 @@ internal override bool GenerateDebugInfo internal override bool IsDeclaredReadOnly => UnderlyingMethod.IsDeclaredReadOnly; - internal sealed override bool IsInitOnly => UnderlyingMethod.IsInitOnly; + internal override bool IsInitOnly => UnderlyingMethod.IsInitOnly; } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InitOnlyMemberTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InitOnlyMemberTests.cs index 0edbf1e93051d..4fee9d4b29047 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InitOnlyMemberTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InitOnlyMemberTests.cs @@ -2128,7 +2128,7 @@ int P2 } [Fact] - public void ModReqOnAccessorParameter() + public void ModReqOnSetAccessorParameter() { string il = @" .class public auto ansi beforefieldinit C extends System.Object @@ -2184,6 +2184,67 @@ public class Derived2 : C ); } + [Fact] + public void ModReqOnGetAccessorReturnValue() + { + string il = @" +.class public auto ansi beforefieldinit C extends System.Object +{ + .method public hidebysig specialname newslot virtual instance int32 modreq(System.Runtime.CompilerServices.IsExternalInit) get_Property () cil managed + { + IL_0000: ldnull + IL_0001: throw + } + + .method public hidebysig specialname newslot virtual instance void set_Property ( int32 'value' ) cil managed + { + IL_0000: ldnull + IL_0001: throw + } + + .method public hidebysig specialname rtspecialname instance void .ctor () cil managed + { + IL_0000: ldnull + IL_0001: throw + } + + .property instance int32 Property() + { + .get instance int32 modreq(System.Runtime.CompilerServices.IsExternalInit) C::get_Property() + .set instance void C::set_Property(int32) + } +} + +.class public auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsExternalInit extends System.Object +{ + .method public hidebysig specialname rtspecialname instance void .ctor () cil managed + { + IL_0000: ldnull + IL_0001: throw + } +} +"; + + string source = @" +public class Derived : C +{ + public override int Property { get { throw null; } } +} +public class Derived2 : C +{ + public override int Property { get { throw null; } } +} +"; + + var reference = CreateMetadataReferenceFromIlSource(il); + var comp = CreateCompilation(source, references: new[] { reference }, parseOptions: TestOptions.RegularPreview); + comp.VerifyDiagnostics(); + + var property = (PEPropertySymbol)comp.GlobalNamespace.GetMember("C.Property"); + Assert.False(property.GetMethod.IsInitOnly); + Assert.False(property.SetMethod.IsInitOnly); + } + [Fact] public void TestSyntaxFacts() { diff --git a/src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs b/src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs index f78e71e2d29d2..968bb29819016 100644 --- a/src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs +++ b/src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs @@ -1187,6 +1187,7 @@ private void DecodeParameterOrThrow(ref BlobReader signatureReader, /*out*/ ref var allowedRequiredModifiers = AllowedRequiredModifierType.System_Runtime_InteropServices_InAttribute; if (isReturn) { + // PROTOTYPE(init-only): can we make this more restrictive (ie. disallow aside from the return value of a setter)? allowedRequiredModifiers |= AllowedRequiredModifierType.System_Runtime_CompilerServices_IsExternalInit; } diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/SymbolFactory.vb b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/SymbolFactory.vb index d154ca3221462..45d526b738f48 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/SymbolFactory.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/SymbolFactory.vb @@ -62,7 +62,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE End Function Friend Overrides Function IsAcceptedIsExternalInitModifierType(type As TypeSymbol) As Boolean - ' VB doesn't deal with init-only members. + ' PROTOTYPE(init-only): VB doesn't deal with init-only members yet. Return False End Function