From f936bbcdbb4bace7b16e8b482aab6dda3733b3c9 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Tue, 20 Dec 2022 16:36:19 -0800 Subject: [PATCH] Fill out all tests --- src/Compilers/Test/Core/CommonTestBase.cs | 36 +- .../VisualBasic/CompilationTestUtils.vb | 2 +- .../Semantics/RequiredMembersTests.vb | 641 ++++++++++++++++-- 3 files changed, 627 insertions(+), 52 deletions(-) diff --git a/src/Compilers/Test/Core/CommonTestBase.cs b/src/Compilers/Test/Core/CommonTestBase.cs index 24abbb594e74f..cee974a6e2c79 100644 --- a/src/Compilers/Test/Core/CommonTestBase.cs +++ b/src/Compilers/Test/Core/CommonTestBase.cs @@ -14,6 +14,7 @@ using System.Text; using System.Xml.Linq; using Microsoft.CodeAnalysis.CodeGen; +using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.Operations; @@ -302,9 +303,33 @@ protected CSharp.CSharpCompilation CreateCSharpCompilation( IEnumerable referencedAssemblies = null, IEnumerable referencedCompilations = null) { + return CreateCSharpCompilation(assemblyName, assemblyIdentity: null, code, parseOptions, compilationOptions, referencedAssemblies, referencedCompilations); + } + + protected CSharp.CSharpCompilation CreateCSharpCompilation( + AssemblyIdentity assemblyIdentity, + string code, + CSharp.CSharpParseOptions parseOptions = null, + CSharp.CSharpCompilationOptions compilationOptions = null, + IEnumerable referencedAssemblies = null, + IEnumerable referencedCompilations = null) + { + return CreateCSharpCompilation(assemblyName: null, assemblyIdentity, code, parseOptions, compilationOptions, referencedAssemblies, referencedCompilations); + } + + private CSharp.CSharpCompilation CreateCSharpCompilation( + string assemblyName, + AssemblyIdentity assemblyIdentity, + string code, + CSharp.CSharpParseOptions parseOptions = null, + CSharp.CSharpCompilationOptions compilationOptions = null, + IEnumerable referencedAssemblies = null, + IEnumerable referencedCompilations = null) + { + Debug.Assert(assemblyName == null || assemblyIdentity == null || assemblyIdentity.Name == assemblyName); if (assemblyName == null) { - assemblyName = GetUniqueName(); + assemblyName = assemblyIdentity?.Name ?? GetUniqueName(); } if (parseOptions == null) @@ -336,7 +361,14 @@ protected CSharp.CSharpCompilation CreateCSharpCompilation( var tree = CSharp.SyntaxFactory.ParseSyntaxTree(SourceText.From(code, encoding: null, SourceHashAlgorithms.Default), options: parseOptions); - return CSharp.CSharpCompilation.Create(assemblyName, new[] { tree }, references, compilationOptions); + var compilation = CSharp.CSharpCompilation.Create(assemblyName, new[] { tree }, references, compilationOptions); + + if (assemblyIdentity != null) + { + ((SourceAssemblySymbol)compilation.Assembly).lazyAssemblyIdentity = assemblyIdentity; + } + + return compilation; } protected VisualBasic.VisualBasicCompilation CreateVisualBasicCompilation( diff --git a/src/Compilers/Test/Utilities/VisualBasic/CompilationTestUtils.vb b/src/Compilers/Test/Utilities/VisualBasic/CompilationTestUtils.vb index a07cdc63ee720..a39b2dd93158a 100644 --- a/src/Compilers/Test/Utilities/VisualBasic/CompilationTestUtils.vb +++ b/src/Compilers/Test/Utilities/VisualBasic/CompilationTestUtils.vb @@ -947,7 +947,7 @@ Friend Module CompilationUtils actualLine = actualReader.ReadLine() End While - Assert.Equal(expectedPooledBuilder.ToStringAndFree(), actualPooledBuilder.ToStringAndFree()) + AssertEx.Equal(expectedPooledBuilder.ToStringAndFree(), actualPooledBuilder.ToStringAndFree()) End Sub ' There are certain cases where multiple distinct errors are diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb index 17be6bbf99451..fc5a896d0d29b 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb @@ -1,144 +1,687 @@ ' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.CSharp +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.CodeAnalysis.VisualBasic.Symbols +Imports Roslyn.Test.Utilities + Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Public Class RequiredMembersTests Inherits BasicTestBase + Private Function CreateCSharpCompilationWithRequiredMembers(source As String) As CSharpCompilation + Return CreateCSharpCompilation(source, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + End Function + Public Sub CannotInheritFromTypesWithRequiredMembers() - + Dim csharp = " +public class Base +{ + public required int Field { get; set; } +} +public class Derived : Base {}" + + Dim csharpReference = CreateCSharpCompilationWithRequiredMembers(csharp).EmitToImageReference() + + Dim vb = CreateCompilation(" +Class VbDerivedBase + Inherits Base +End Class + +Class VbDerivedDerived + Inherits Derived +End Class", references:={csharpReference}) + + vb.AssertTheseDiagnostics( +BC37322: Cannot inherit from 'Base' because it has required members. + Inherits Base + ~~~~~~~~~~~~~ +BC37322: Cannot inherit from 'Derived' because it has required members. + Inherits Derived + ~~~~~~~~~~~~~~~~ +) End Sub - - Public Sub EnforcedRequiredMembers_NoInheritance_NoneSet( constructor As String) + Private Function GetCDefinition(hasSetsRequiredMembers As Boolean, Optional typeKind As String = "class") As String + Return $" +using System.Diagnostics.CodeAnalysis; +public {typeKind} C +{{ + public required int Prop {{ get; set; }} + public required int Field; - End Sub + {If(hasSetsRequiredMembers, "[SetsRequiredMembers]", "")} + public C() {{}} +}}" + End Function - Public Sub EnforcedRequiredMembers_NoInheritance_PartialSet( constructor As String) - + + Public Sub EnforcedRequiredMembers_NoInheritance_NoneSet( constructor As String) + + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetCDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Field As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> + ~ +BC37321: Required member 'Public Overloads Property Prop As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> + ~ + ) End Sub - Public Sub EnforcedRequiredMembers_NoInheritance_AllSet( constructor As String) - + + Public Sub EnforcedRequiredMembers_NoInheritance_PartialSet( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetCDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} With {{ .Prop = 1 }} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Field As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> With { .Prop = 1 } + ~ + ) End Sub - Public Sub EnforcedRequiredMembers_NoInheritance_HasSetsRequiredMembers( constructor As String) + + Public Sub EnforcedRequiredMembers_NoInheritance_AllSet( constructor As String) - End Sub + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetCDefinition(hasSetsRequiredMembers:=False)) - - Public Sub EnforcedRequiredMembers_NoInheritance_Unsettable( constructor As String) + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} With {{ .Prop = 1, .Field = 2 }} + End Sub +End Module" + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics() End Sub - Public Sub EnforcedRequiredMembers_Inheritance_NoneSet( constructor As String) - + + Public Sub EnforcedRequiredMembers_NoInheritance_HasSetsRequiredMembers( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetCDefinition(hasSetsRequiredMembers:=True)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics End Sub - - Public Sub EnforcedRequiredMembers_Inheritance_PartialSet( constructor As String) + Private Function GetBaseDerivedDefinition(hasSetsRequiredMembers As Boolean) As String + Return $" +using System.Diagnostics.CodeAnalysis; +public class Base +{{ + public required int Prop1 {{ get; set; }} + public required int Field1; + + {If(hasSetsRequiredMembers, "[SetsRequiredMembers]", "")} + public Base() {{}} +}} +public class Derived : Base +{{ + public required int Prop2 {{ get; set; }} + public required int Field2; + + {If(hasSetsRequiredMembers, "[SetsRequiredMembers]", "")} + public Derived() {{}} +}} +public class DerivedDerived : Derived +{{ + {If(hasSetsRequiredMembers, "[SetsRequiredMembers]", "")} + public DerivedDerived() {{}} +}}" + End Function + + + Public Sub EnforcedRequiredMembers_Inheritance_NoneSet( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetBaseDerivedDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Field1 As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> + ~~~~~~~~~~~~~~ +BC37321: Required member 'Public Field2 As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> + ~~~~~~~~~~~~~~ +BC37321: Required member 'Public Overloads Property Prop1 As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> + ~~~~~~~~~~~~~~ +BC37321: Required member 'Public Overloads Property Prop2 As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> + ~~~~~~~~~~~~~~ + ) End Sub - Public Sub EnforcedRequiredMembers_Inheritance_AllSet( constructor As String) - + + Public Sub EnforcedRequiredMembers_Inheritance_PartialSet( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetBaseDerivedDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} With {{ .Prop1 = 1, .Field2 = 2 }} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Field1 As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> With { .Prop1 = 1, .Field2 = 2 } + ~~~~~~~~~~~~~~ +BC37321: Required member 'Public Overloads Property Prop2 As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> With { .Prop1 = 1, .Field2 = 2 } + ~~~~~~~~~~~~~~ + ) End Sub - Public Sub EnforcedRequiredMembers_Inheritance_NoneSet_HasSetsRequiredMembers( constructor As String) - + + Public Sub EnforcedRequiredMembers_Inheritance_AllSet( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetBaseDerivedDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} With {{ .Prop1 = 1, .Prop2 = 2, .Field1 = 1, .Field2 = 2 }} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics() End Sub - Public Sub EnforcedRequiredMembers_Inheritance_NoMembersOnDerivedType( constructor As String) + + Public Sub EnforcedRequiredMembers_Inheritance_NoneSet_HasSetsRequiredMembers( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetBaseDerivedDefinition(hasSetsRequiredMembers:=True)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics() + End Sub + + Public Sub EnforcedRequiredMembers_ThroughRetargeting_NoneSet() + Dim retargetedCode = GetCDefinition(hasSetsRequiredMembers:=False) + + Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + + Dim originalBasic = CreateCompilation(" +Public Class Base + Public Property C As C +End Class", {originalC.EmitToImageReference()}) + + Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + + Dim comp = CreateCompilation(" +Module M + Public Sub Main() + Dim b As New Base() With { .C = New C() } + End Sub +End Module", {originalBasic.ToMetadataReference(), retargetedC.EmitToImageReference()}) + + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Field As Integer' must be set in the object initializer or attribute constructor. + Dim b As New Base() With { .C = New C() } + ~ +BC37321: Required member 'Public Overloads Property Prop As Integer' must be set in the object initializer or attribute constructor. + Dim b As New Base() With { .C = New C() } + ~ + ) End Sub - Public Sub EnforcedRequiredMembers_ThroughRetargeting_NoneSet( constructor As String) + + Public Sub EnforcedRequiredMembers_ThroughRetargeting_AllSet( constructor As String) + Dim retargetedCode = GetCDefinition(hasSetsRequiredMembers:=False) - End Sub + Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) - - Public Sub EnforcedRequiredMembers_ThroughRetargeting_AllSet( constructor As String) + Dim originalBasic = CreateCompilation(" +Public Class Base + Public Property C As C +End Class", {originalC.EmitToImageReference()}) - End Sub + Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) - - Public Sub EnforcedRequiredMembers_ThroughRetargeting_HasSetsRequiredMembers( constructor As String) + Dim comp = CreateCompilation(" +Module M + Public Sub Main() + Dim b As New Base() With { .C = New C() With { .Field = 1, .Prop = 1 } } + End Sub +End Module", {originalBasic.ToMetadataReference(), retargetedC.EmitToImageReference()}) + comp.AssertNoDiagnostics() End Sub - Public Sub EnforcedRequiredMembers_Override_NoneSet( constructor As String) + + Public Sub EnforcedRequiredMembers_ThroughRetargeting_HasSetsRequiredMembers( constructor As String) + + Dim retargetedCode = GetCDefinition(hasSetsRequiredMembers:=True) + Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + + Dim originalBasic = CreateCompilation(" +Public Class Base + Public Property C As C +End Class", {originalC.EmitToImageReference()}) + + Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + + Dim comp = CreateCompilation(" +Module M + Public Sub Main() + Dim b As New Base() With { .C = New C() } + End Sub +End Module", {originalBasic.ToMetadataReference(), retargetedC.EmitToImageReference()}) + + comp.AssertNoDiagnostics() End Sub - - Public Sub EnforcedRequiredMembers_Override_AllSet( constructor As String) + Private Function GetDerivedOverrideDefinition(hasSetsRequiredMembers As Boolean) As String + Return $" +using System.Diagnostics.CodeAnalysis; +public class Base +{{ + public virtual required int Prop {{ get; set; }} + + {If(hasSetsRequiredMembers, "[SetsRequiredMembers]", "")} + public Base() {{}} +}} +public class Derived : Base +{{ + public override required int Prop {{ get; set; }} + + {If(hasSetsRequiredMembers, "[SetsRequiredMembers]", "")} + public Derived() {{}} +}}" + End Function + + + Public Sub EnforcedRequiredMembers_Override_NoneSet( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetDerivedOverrideDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Overrides Property Prop As Integer' must be set in the object initializer or attribute constructor. + Dim t <%= constructor %> + ~~~~~~~ + ) End Sub - Public Sub EnforcedRequiredMembers_Override_HasSetsRequiredMembers( constructor As String) + + Public Sub EnforcedRequiredMembers_Override_AllSet( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetDerivedOverrideDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} With {{ .Prop = 1 }} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics() + End Sub + + + Public Sub EnforcedRequiredMembers_Override_HasSetsRequiredMembers( constructor As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetDerivedOverrideDefinition(hasSetsRequiredMembers:=True)) + + Dim vbCode = $" +Module M + Sub Main() + Dim t {constructor} + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics() End Sub Public Sub EnforcedRequiredMembers_ShadowedFromMetadata_01() + Dim malformedDefinition = CreateCompilation(" +Imports System.Diagnostics.CodeAnalysis +Imports System.Runtime.CompilerServices + +Public Class Base + + Public Property P As Integer +End Class + + +Public Class Derived + Inherits Base + + Public Shadows Property P As Integer + + Public Sub New() + End Sub + + + Public Sub New(unused As Integer) + End Sub +End Class +", targetFramework:=TargetFramework.Net70) + + Dim comp = CreateCompilation(" +Module M + Sub Main() + Dim d1 = New Derived() + Dim d2 = New Derived(1) + End Sub +End Module", {malformedDefinition.EmitToImageReference()}) + + comp.AssertTheseDiagnostics( +BC37323: The required members list for 'Derived' is malformed and cannot be interpreted. + Dim d1 = New Derived() + ~~~~~~~~~~~~~ + ) + End Sub + + Public Sub EnforcedRequiredMembers_ShadowedFromMetadata_02() + Dim malformedDefinition = CreateCompilation(" +Imports System.Diagnostics.CodeAnalysis +Imports System.Runtime.CompilerServices + +Public Class Base + + Public Property P As Integer +End Class + + +Public Class Derived + Inherits Base + Public Shadows Property P As Integer + + Public Sub New() + End Sub + + + Public Sub New(unused As Integer) + End Sub +End Class +", targetFramework:=TargetFramework.Net70) + + Dim comp = CreateCompilation(" +Module M + Sub Main() + Dim d1 = New Derived() + Dim d2 = New Derived(1) + End Sub +End Module", {malformedDefinition.EmitToImageReference()}) + + comp.AssertTheseDiagnostics( +BC37323: The required members list for 'Derived' is malformed and cannot be interpreted. + Dim d1 = New Derived() + ~~~~~~~~~~~~~ + ) End Sub - Public Sub CoClassWithRequiredMembers_NoneSet() + Public Sub EnforcedRequiredMembers_ShadowedFromMetadata_03() + Dim malformedDefinition = CreateCompilation(" +Imports System.Diagnostics.CodeAnalysis +Imports System.Runtime.CompilerServices + +Public Class Base + + Public Property P As Integer +End Class + +Public Class Derived + Inherits Base + Public Shadows Property P As Integer + + Public Sub New() + End Sub + + + Public Sub New(unused As Integer) + End Sub +End Class +", targetFramework:=TargetFramework.Net70) + + Dim comp = CreateCompilation(" +Module M + Sub Main() + Dim d1 = New Derived() + Dim d2 = New Derived(1) + End Sub +End Module", {malformedDefinition.EmitToImageReference()}) + + comp.AssertTheseDiagnostics( +BC37323: The required members list for 'Derived' is malformed and cannot be interpreted. + Dim d1 = New Derived() + ~~~~~~~~~~~~~ + ) + End Sub + + Public Sub CoClassWithRequiredMembers_NoneSet() + Dim cComp = CreateCSharpCompilationWithRequiredMembers(" +using System; +using System.Runtime.InteropServices; + +[ComImport, Guid(""00020810-0000-0000-C000-000000000046"")] +[CoClass(typeof(C))] +public interface I +{ +} + +public class C : I +{ + public required int P { get; set; } +} +") + Dim comp = CreateCompilation(" +Module M + Sub Main() + Dim i = New I() + End Sub +End Module", {cComp.EmitToImageReference()}) + + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Overloads Property P As Integer' must be set in the object initializer or attribute constructor. + Dim i = New I() + ~ + ) End Sub Public Sub CoClassWithRequiredMembers_AllSet() - + Dim cComp = CreateCSharpCompilationWithRequiredMembers(" +using System; +using System.Runtime.InteropServices; + +[ComImport, Guid(""00020810-0000-0000-C000-000000000046"")] +[CoClass(typeof(C))] +public interface I +{ + public int P { get; set; } +} + +public class C : I +{ + public required int P { get; set; } +} +") + Dim comp = CreateCompilation(" +Module M + Sub Main() + Dim i = New I() With { .P = 1 } + End Sub +End Module", {cComp.EmitToImageReference()}) + + comp.AssertTheseDiagnostics( +BC37321: Required member 'Public Overloads Property P As Integer' must be set in the object initializer or attribute constructor. + Dim i = New I() With { .P = 1 } + ~ + ) End Sub + Public Function GetAttributeDefinition(hasSetsRequiredMembers As Boolean) As String + Return $" +using System; +public class AttrAttribute : Attribute +{{ + {If(hasSetsRequiredMembers, "[SetsRequiredMembers]", "")} + public AttrAttribute() {{}} + + public required int P {{ get; set; }} +}} +" + End Function + Public Sub RequiredMemberInAttribute_NoneSet() - + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetAttributeDefinition(hasSetsRequiredMembers:=False)) + + Dim vbCode = $" + +Class C +End Class" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertTheseDiagnostics( + ~~~~ +]]>) End Sub Public Sub RequiredMemberInAttribute_AllSet() + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetAttributeDefinition(hasSetsRequiredMembers:=False)) - End Sub - - - - - Public Sub ForbidRequiredAsNew_NoInheritance(typeKind As String) + Dim vbCode = $" + +Class C +End Class" + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics() End Sub - Public Sub ForbidRequiredAsNew_Inheritance() + Public Sub PublicAPITests() + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetCDefinition(hasSetsRequiredMembers:=False)) - End Sub + Dim vbComp = CreateCompilation("", {cComp.EmitToImageReference()}) - - - - Public Sub AllowRequiredAsNew_SetsRequiredMembersOnConstructor(typeKind As String) + Dim c = vbComp.GetTypeByMetadataName("C") + Assert.False(c.HasRequiredMembersError) + Dim prop = c.GetMember(Of PropertySymbol)("Prop") + Dim field = c.GetMember(Of FieldSymbol)("Field") + + AssertEx.Equal(Of Symbol)({field, prop}, From kvp In c.AllRequiredMembers + Order By kvp.Key + Select kvp.Value) + Assert.True(prop.IsRequired) + Assert.True(field.IsRequired) End Sub - - Public Sub PublicAPITests(isRequired As Boolean) + + + Public Sub GenericConstrainedToNew_Forbidden(typeKind As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetCDefinition(hasSetsRequiredMembers:=False, typeKind)) + + Dim vbCode = " +Module M + Sub Main() + Generic(Of C)() + End Sub + + Sub Generic(Of T As New)() + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertTheseDiagnostics( +BC37324: 'C' cannot satisfy the 'New' constraint on parameter 'T' in the generic type or or method 'Public Sub Generic(Of T As New)()' because 'C' has required members. + Generic(Of C)() + ~~~~~~~~~~~~~ + ) + End Sub + + + + Public Sub GenericConstrainedToNew_HasSetsRequiredMembers_Allowed(typeKind As String) + Dim cComp = CreateCSharpCompilationWithRequiredMembers(GetCDefinition(hasSetsRequiredMembers:=True, typeKind)) + + Dim vbCode = " +Module M + Sub Main() + Generic(Of C)() + End Sub + + Sub Generic(Of T As New)() + End Sub +End Module" + + Dim comp = CreateCompilation(vbCode, {cComp.EmitToImageReference()}) + comp.AssertNoDiagnostics() End Sub End Class End Namespace