Skip to content

IAssemblySymbol.GivesAccessTo returns incorrect result cross languages #26459

@gafter

Description

@gafter

The following test demonstrates that IAssemblySymbol.GivesAccessTo gives an incorrect result when the two assemblies result from compilations in different languages. The consequence of this bug is that the new extension API ISymbol.IsAccessibleWithin gives an incorrect result for some cases across languages.

        [Fact]
        public void TestCrossCompilationIVT()
        {
            var csharpTree = CSharpSyntaxTree.ParseText(@"
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(""VB"")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(""CS2"")]
internal class CS
{
}
");
            var csharpTree2 = CSharpSyntaxTree.ParseText(@"
internal class CS2
{
}
");
            var vbTree = VisualBasicSyntaxTree.ParseText(@"
<assembly: System.Runtime.CompilerServices.InternalsVisibleTo(""CS"")>
<assembly: System.Runtime.CompilerServices.InternalsVisibleTo(""VB2"")>
Friend Class VB
End Class
");
            var vbTree2 = VisualBasicSyntaxTree.ParseText(@"
Friend Class VB2
End Class
");
            var csc = CSharpCompilation.Create("CS", new[] { csharpTree }, new MetadataReference[] { TestBase.MscorlibRef });
            var CS = csc.GlobalNamespace.GetMembers("CS")[0] as INamedTypeSymbol;

            var csc2 = CSharpCompilation.Create("CS2", new[] { csharpTree2 }, new MetadataReference[] { TestBase.MscorlibRef });
            var CS2 = csc2.GlobalNamespace.GetMembers("CS2")[0] as INamedTypeSymbol;

            var vbc = VisualBasicCompilation.Create("VB", new[] { vbTree }, new MetadataReference[] { TestBase.MscorlibRef });
            var VB = vbc.GlobalNamespace.GetMembers("VB")[0] as INamedTypeSymbol;

            var vbc2 = VisualBasicCompilation.Create("VB2", new[] { vbTree2 }, new MetadataReference[] { TestBase.MscorlibRef });
            var VB2 = vbc2.GlobalNamespace.GetMembers("VB2")[0] as INamedTypeSymbol;

            // The following results are correct
            Assert.True(CS.ContainingAssembly.GivesAccessTo(CS2.ContainingAssembly));
            Assert.True(VB.ContainingAssembly.GivesAccessTo(VB2.ContainingAssembly));
            Assert.True(CS.IsAccessibleWithin(CS2));
            Assert.True(VB.IsAccessibleWithin(VB2));

            // The following results are incorrect
            Assert.False(CS.ContainingAssembly.GivesAccessTo(VB.ContainingAssembly)); // should be Assert.True
            Assert.False(VB.ContainingAssembly.GivesAccessTo(CS.ContainingAssembly)); // should be Assert.True
            Assert.False(CS.IsAccessibleWithin(VB)); // should be Assert.True
            Assert.False(VB.IsAccessibleWithin(CS)); // should be Assert.True
        }

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions