Skip to content

Commit dba696f

Browse files
authored
Merge pull request #163 from meziantou/polyfill/fix-duplicate-member-generation
Fix duplicate member generation when multiple IVT assemblies reference polyfill
2 parents 1d4b1d5 + 2d2d4fa commit dba696f

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

Meziantou.Polyfill.SourceGenerator.Tests/UnitTest1.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,29 @@ public async Task InternalsVisibleTo_DoNotRegenerateExtensionMethods()
8585

8686
}
8787

88+
[Fact]
89+
public async Task InternalsVisibleTo_TwoReferencedAssemblies_DoNotCauseAmbiguity()
90+
{
91+
var assemblies = await NuGetHelpers.GetNuGetReferences("NETStandard.Library", "2.0.3", "build/");
92+
93+
// Generate two assemblies that both expose internals to "main"
94+
var proj2Generation = GenerateFiles("""[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("main")]""", assemblyName: "proj2", assemblyLocations: assemblies);
95+
Assert.Single(GetFileNames(proj2Generation.GeneratorResult), file => file is "T_System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.g.cs");
96+
97+
var proj3Generation = GenerateFiles("""[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("main")]""", assemblyName: "proj3", assemblyLocations: assemblies);
98+
Assert.Single(GetFileNames(proj3Generation.GeneratorResult), file => file is "T_System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.g.cs");
99+
100+
var proj2Dll = Path.GetTempFileName() + ".dll";
101+
var proj3Dll = Path.GetTempFileName() + ".dll";
102+
await File.WriteAllBytesAsync(proj2Dll, proj2Generation.Assembly!);
103+
await File.WriteAllBytesAsync(proj3Dll, proj3Generation.Assembly!);
104+
105+
// "main" references both assemblies. The generator must still produce types
106+
// that would otherwise be ambiguous (CS0433) between proj2 and proj3.
107+
var result = GenerateFiles("", assemblyName: "main", assemblyLocations: assemblies.Append(proj2Dll).Append(proj3Dll));
108+
Assert.Single(GetFileNames(result.GeneratorResult), file => file is "T_System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.g.cs");
109+
}
110+
88111
[Theory]
89112
[MemberData(nameof(GetConfigurations))]
90113
public async Task GeneratedCodeCompile(PackageReference[] packages, bool allowUnsafe)

Meziantou.Polyfill/Members.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,32 @@ private static bool IncludeMember(IncludeContext context, string memberDocumenta
1313
return false;
1414

1515
var symbols = DocumentationCommentId.GetSymbolsForDeclarationId(memberDocumentationId, context.Compilation);
16+
IAssemblySymbol? accessibleFromAssembly = null;
1617
foreach (var symbol in symbols)
1718
{
1819
if (ReferenceEquals(symbol.ContainingAssembly, context.Compilation.Assembly))
1920
return false;
2021

2122
// IsEmbeddedSymbol is a workaround for https://github.com/dotnet/roslyn/issues/79498
2223
if (context.Compilation.IsSymbolAccessibleWithin(symbol, context.Compilation.Assembly) && !IsEmbeddedSymbol(symbol))
23-
return false;
24+
{
25+
if (accessibleFromAssembly is null)
26+
{
27+
accessibleFromAssembly = symbol.ContainingAssembly;
28+
}
29+
else if (!ReferenceEquals(accessibleFromAssembly, symbol.ContainingAssembly))
30+
{
31+
// The symbol is accessible from multiple assemblies, which would cause
32+
// ambiguity (e.g. CS0433). Generate a local copy so the compiler prefers
33+
// the current assembly's definition.
34+
return true;
35+
}
36+
}
2437
}
2538

39+
if (accessibleFromAssembly is not null)
40+
return false;
41+
2642
return true;
2743
}
2844

Meziantou.Polyfill/Meziantou.Polyfill.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Meziantou.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>netstandard2.0</TargetFrameworks>
4-
<Version>1.0.105</Version>
4+
<Version>1.0.106</Version>
55
<TransformOnBuild>true</TransformOnBuild>
66
<RoslynVersion>4.3.1</RoslynVersion>
77

0 commit comments

Comments
 (0)