File: CommandLineIVTTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\CommandLine\Microsoft.CodeAnalysis.CSharp.CommandLine.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.CommandLine.UnitTests)
// 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.
 
using System.IO;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.CommandLine.UnitTests;
 
public class CommandLineIVTTests : CommandLineTestBase
{
    [Fact]
    public void InaccessibleBaseType()
    {
        var source1 = """
            namespace N1;
            internal class A {}
            """;
 
        var comp1 = CreateCompilation(source1, options: TestOptions.DebugDll, assemblyName: "N1", targetFramework: TargetFramework.Mscorlib461);
 
        var dir = Temp.CreateDirectory();
 
        var source2 = dir.CreateFile("B.cs").WriteAllText("""
            namespace N2;
            internal class B : N1.A {}
            """);
 
        var sw = new StringWriter();
 
        var compiler = CreateCSharpCompiler(new[] {
            "/nologo",
            "/t:library",
            "/preferreduilang:en",
            "/reportivts",
            source2.Path,
        }, additionalReferences: new[] { comp1.ToMetadataReference() });
 
        var errorCode = compiler.Run(sw);
 
        Assert.Equal(CommonCompiler.Failed, errorCode);
        var outputFilePath = $"{Path.GetFileName(dir.Path)}{Path.DirectorySeparatorChar}{Path.GetFileName(source2.Path)}";
        AssertEx.AssertEqualToleratingWhitespaceDifferences($"""
{outputFilePath}(2,23): error CS0122: 'A' is inaccessible due to its protection level
{outputFilePath}(2,23): error CS9163: 'A' is defined in assembly 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
 
Printing 'InternalsVisibleToAttribute' information for the current compilation and all referenced assemblies.
Current assembly: 'B, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
 
Assembly reference: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000'
  Grants IVT to current assembly: False
  Grants IVTs to:
    Assembly name: 'PresentationCore'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'PresentationFramework'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'System'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Core'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Numerics'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Reflection.Context'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime.UI.Xaml'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'WindowsBase'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
 
Assembly reference: 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
  Grants IVT to current assembly: False
  Grants IVTs to:
    Nothing
""", sw.ToString().Trim());
    }
 
    [Fact]
    public void AccessibleBaseType()
    {
        var source1 = """
            [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("B")]
            namespace N1;
            internal class A {}
            """;
 
        var comp1 = CreateCompilation(source1, options: TestOptions.DebugDll, assemblyName: "N1", targetFramework: TargetFramework.Mscorlib461);
 
        var dir = Temp.CreateDirectory();
 
        var source2 = dir.CreateFile("B.cs").WriteAllText("""
            namespace N2;
            internal class B : N1.A {}
            """);
 
        var sw = new StringWriter();
 
        var compiler = CreateCSharpCompiler(new[] {
            "/nologo",
            "/t:library",
            "/preferreduilang:en",
            "/reportivts",
            source2.Path,
        }, additionalReferences: new[] { comp1.ToMetadataReference() });
 
        var errorCode = compiler.Run(sw);
 
        Assert.Equal(CommonCompiler.Succeeded, errorCode);
        var outputFilePath = $"{Path.GetFileName(dir.Path)}{Path.DirectorySeparatorChar}{Path.GetFileName(source2.Path)}";
        AssertEx.AssertEqualToleratingWhitespaceDifferences($"""

Printing 'InternalsVisibleToAttribute' information for the current compilation and all referenced assemblies.
Current assembly: 'B, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
 
Assembly reference: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000'
  Grants IVT to current assembly: False
  Grants IVTs to:
    Assembly name: 'PresentationCore'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'PresentationFramework'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'System'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Core'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Numerics'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Reflection.Context'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime.UI.Xaml'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'WindowsBase'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
 
Assembly reference: 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
  Grants IVT to current assembly: True
  Grants IVTs to:
    Assembly name: 'B'
    Public Keys:
""", sw.ToString().Trim());
    }
 
    [Fact]
    public void InaccessibleGetterSetter()
    {
        var source1 = """
            namespace N1;
            public class A
            {
                internal string Prop { get; set; }
            }
            """;
 
        var comp1 = CreateCompilation(source1, options: TestOptions.DebugDll, assemblyName: "N1", targetFramework: TargetFramework.Mscorlib461);
 
        var dir = Temp.CreateDirectory();
 
        var source2 = dir.CreateFile("B.cs").WriteAllText("""
            var a = new N1.A();
            _ = a.Prop;
            a.Prop = "hello";
            """);
 
        var sw = new StringWriter();
 
        var compiler = CreateCSharpCompiler(new[] {
            "/nologo",
            "/t:exe",
            "/preferreduilang:en",
            "/reportivts",
            source2.Path,
        }, additionalReferences: new[] { comp1.ToMetadataReference() });
 
        var errorCode = compiler.Run(sw);
 
        Assert.Equal(CommonCompiler.Failed, errorCode);
        var outputFilePath = $"{Path.GetFileName(dir.Path)}{Path.DirectorySeparatorChar}{Path.GetFileName(source2.Path)}";
        AssertEx.AssertEqualToleratingWhitespaceDifferences($"""
{outputFilePath}(2,7): error CS0122: 'A.Prop' is inaccessible due to its protection level
{outputFilePath}(3,3): error CS0122: 'A.Prop' is inaccessible due to its protection level
{outputFilePath}(2,7): error CS9163: 'A.Prop' is defined in assembly 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
{outputFilePath}(3,3): error CS9163: 'A.Prop' is defined in assembly 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
 
Printing 'InternalsVisibleToAttribute' information for the current compilation and all referenced assemblies.
Current assembly: '?, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
 
Assembly reference: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000'
  Grants IVT to current assembly: False
  Grants IVTs to:
    Assembly name: 'PresentationCore'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'PresentationFramework'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'System'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Core'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Numerics'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Reflection.Context'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime.UI.Xaml'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'WindowsBase'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
 
Assembly reference: 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
  Grants IVT to current assembly: False
  Grants IVTs to:
    Nothing

""", sw.ToString().Trim());
    }
 
    [Fact]
    public void InaccessibleImplicitInterfaceImpl()
    {
        var source1 = """
            namespace N1;
            public interface A
            {
                internal void M();
            }
            """;
 
        var comp1 = CreateCompilation(source1, options: TestOptions.DebugDll, assemblyName: "N1", targetFramework: TargetFramework.Mscorlib461);
 
        var dir = Temp.CreateDirectory();
 
        var source2 = dir.CreateFile("B.cs").WriteAllText("""
            namespace N2;
            public class B : N1.A
            {
                public void M() { }
            }
            """);
 
        var sw = new StringWriter();
 
        var compiler = CreateCSharpCompiler(new[] {
            "/nologo",
            "/t:library",
            "/preferreduilang:en",
            "/reportivts",
            source2.Path,
        }, additionalReferences: new[] { comp1.ToMetadataReference() });
 
        var errorCode = compiler.Run(sw);
 
        Assert.Equal(CommonCompiler.Failed, errorCode);
        var outputFilePath = $"{Path.GetFileName(dir.Path)}{Path.DirectorySeparatorChar}{Path.GetFileName(source2.Path)}";
        AssertEx.AssertEqualToleratingWhitespaceDifferences($"""
{outputFilePath}(4,17): error CS9044: 'B' does not implement interface member 'A.M()'. 'B.M()' cannot implicitly implement an inaccessible member.
{outputFilePath}(4,17): error CS9163: 'A.M()' is defined in assembly 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
 
Printing 'InternalsVisibleToAttribute' information for the current compilation and all referenced assemblies.
Current assembly: 'B, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
 
Assembly reference: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKey=00000000000000000400000000000000'
  Grants IVT to current assembly: False
  Grants IVTs to:
    Assembly name: 'PresentationCore'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'PresentationFramework'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
    Assembly name: 'System'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Core'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Numerics'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Reflection.Context'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'System.Runtime.WindowsRuntime.UI.Xaml'
    Public Keys:
      00000000000000000400000000000000
    Assembly name: 'WindowsBase'
    Public Keys:
      0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9
 
Assembly reference: 'N1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
  Grants IVT to current assembly: False
  Grants IVTs to:
    Nothing
""", sw.ToString().Trim());
    }
 
    [Theory]
    [InlineData("/reportivts")]
    [InlineData("/reportivts+")]
    public void TurnOnLast(string onFlag)
    {
        var compiler = CreateCSharpCompiler(new[] {
            "/nologo",
            "/reportivts-",
            onFlag,
        });
 
        Assert.True(compiler.Arguments.ReportInternalsVisibleToAttributes);
    }
 
    [Theory]
    [InlineData("/reportivts")]
    [InlineData("/reportivts+")]
    public void TurnOffLast(string onFlag)
    {
        var compiler = CreateCSharpCompiler(new[] {
            "/nologo",
            onFlag,
            "/reportivts-",
        });
 
        Assert.False(compiler.Arguments.ReportInternalsVisibleToAttributes);
    }
 
    [Fact]
    public void BadReportIvtsValue()
    {
        var compiler = CreateCSharpCompiler(new[] {
            "/nologo",
            "/reportivts:bad",
        });
 
        Assert.False(compiler.Arguments.ReportInternalsVisibleToAttributes);
        compiler.Arguments.Errors.Verify(
            Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/reportivts:bad").WithLocation(1, 1),
            Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1),
            Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1)
        );
    }
}