Skip to content

Commit eb3f5ba

Browse files
authored
Silently treat IncludePrivateMembers as true when emitting regular assemblies (#21359)
1 parent 468d3c9 commit eb3f5ba

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs

+34-3
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,36 @@ public class PublicClass
15761576
"System.Diagnostics.DebuggableAttribute" },
15771577
compWithReal.SourceModule.GetReferencedAssemblySymbols().Last().GetAttributes().Select(a => a.AttributeClass.ToTestDisplayString()));
15781578

1579+
// Verify metadata (types, members, attributes) of the regular assembly with IncludePrivateMembers accidentally set to false.
1580+
// Note this can happen because of binary clients compiled against old EmitOptions ctor which had IncludePrivateMembers=false by default.
1581+
// In this case, IncludePrivateMembers is silently set to true when emitting
1582+
// See https://github.com/dotnet/roslyn/issues/20873
1583+
var emitRegularWithoutPrivateMembers = EmitOptions.Default.WithIncludePrivateMembers(false);
1584+
CompileAndVerify(comp, emitOptions: emitRegularWithoutPrivateMembers, verify: true);
1585+
1586+
var realImage2 = comp.EmitToImageReference(emitRegularWithoutPrivateMembers);
1587+
var compWithReal2 = CreateCompilation("", references: new[] { MscorlibRef, realImage2 },
1588+
options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All));
1589+
AssertEx.Equal(
1590+
new[] { "<Module>", "<>f__AnonymousType0<<anonymous>j__TPar>", "PublicClass" },
1591+
compWithReal2.SourceModule.GetReferencedAssemblySymbols().Last().GlobalNamespace.GetMembers().Select(m => m.ToDisplayString()));
1592+
1593+
AssertEx.Equal(
1594+
new[] { "void PublicClass.PublicMethod()", "void PublicClass.PrivateMethod()",
1595+
"void PublicClass.ProtectedMethod()", "void PublicClass.InternalMethod()",
1596+
"void PublicClass.PublicEvent.add", "void PublicClass.PublicEvent.remove",
1597+
"void PublicClass.InternalEvent.add", "void PublicClass.InternalEvent.remove",
1598+
"PublicClass..ctor()",
1599+
"event System.Action PublicClass.PublicEvent", "event System.Action PublicClass.InternalEvent" },
1600+
compWithReal2.GetMember<NamedTypeSymbol>("PublicClass").GetMembers()
1601+
.Select(m => m.ToTestDisplayString()));
1602+
1603+
AssertEx.Equal(
1604+
new[] { "System.Runtime.CompilerServices.CompilationRelaxationsAttribute",
1605+
"System.Runtime.CompilerServices.RuntimeCompatibilityAttribute",
1606+
"System.Diagnostics.DebuggableAttribute" },
1607+
compWithReal2.SourceModule.GetReferencedAssemblySymbols().Last().GetAttributes().Select(a => a.AttributeClass.ToTestDisplayString()));
1608+
15791609
// verify metadata (types, members, attributes) of the metadata-only assembly
15801610
var emitMetadataOnly = EmitOptions.Default.WithEmitMetadataOnly(true);
15811611
CompileAndVerify(comp, emitOptions: emitMetadataOnly, verify: true);
@@ -1732,15 +1762,16 @@ public void IncludePrivateMembers_DisallowMetadataPeStream()
17321762
}
17331763

17341764
[Fact]
1735-
public void MustIncludePrivateMembersUnlessRefAssembly()
1765+
[WorkItem(20873, "https://github.com/dotnet/roslyn/issues/20873")]
1766+
public void IncludePrivateMembersSilentlyAssumedTrueWhenEmittingRegular()
17361767
{
17371768
CSharpCompilation comp = CreateCompilation("", references: new[] { MscorlibRef },
17381769
options: TestOptions.DebugDll.WithDeterministic(true));
17391770

17401771
using (var output = new MemoryStream())
17411772
{
1742-
Assert.Throws<ArgumentException>(() => comp.Emit(output,
1743-
options: EmitOptions.Default.WithIncludePrivateMembers(false)));
1773+
// no exception
1774+
_ = comp.Emit(output, options: EmitOptions.Default.WithIncludePrivateMembers(false));
17441775
}
17451776
}
17461777

src/Compilers/Core/Portable/Compilation/Compilation.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2086,9 +2086,10 @@ public EmitResult Emit(
20862086
throw new ArgumentException(CodeAnalysisResources.IncludingPrivateMembersUnexpectedWhenEmittingToMetadataPeStream, nameof(metadataPEStream));
20872087
}
20882088

2089-
if (metadataPEStream == null && options?.EmitMetadataOnly == false && options?.IncludePrivateMembers == false)
2089+
if (metadataPEStream == null && options?.EmitMetadataOnly == false)
20902090
{
2091-
throw new ArgumentException(CodeAnalysisResources.MustIncludePrivateMembersUnlessRefAssembly, nameof(options.IncludePrivateMembers));
2091+
// EmitOptions used to default to IncludePrivateMembers=false, so to preserve binary compatibility we silently correct that unless emitting regular assemblies
2092+
options = options.WithIncludePrivateMembers(true);
20922093
}
20932094

20942095
if (options?.DebugInformationFormat == DebugInformationFormat.Embedded &&

0 commit comments

Comments
 (0)