From 1743bab9d005e94745d69310aaef7eb01ff031e4 Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Mon, 21 Nov 2016 15:45:09 -0800 Subject: [PATCH] Provide an API to get unreferenced assembly identities obects from the diagnostics reported about them. --- .../Portable/Compilation/CSharpCompilation.cs | 3 ++ .../Core/Portable/Compilation/Compilation.cs | 39 +++++++++++++++++++ .../Core/Portable/PublicAPI.Unshipped.txt | 1 + .../Compilation/VisualBasicCompilation.vb | 8 ++++ .../Diagnostics/DiagnosticExtensions.cs | 13 +++++++ 5 files changed, 64 insertions(+) diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs index 061f4cc549d..f5bf2f9ca7a 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs @@ -1523,6 +1523,9 @@ private MethodSymbol FindEntryPoint(CancellationToken cancellationToken, out Imm } } + internal override ImmutableArray UnreferencedAssemblyIdentityDiagnosticCodes { get; } + = ImmutableArray.Create((int)ErrorCode.ERR_NoTypeDef); + internal class EntryPoint { public readonly MethodSymbol MethodSymbol; diff --git a/src/Compilers/Core/Portable/Compilation/Compilation.cs b/src/Compilers/Core/Portable/Compilation/Compilation.cs index 1a8748bb290..c42c6040102 100644 --- a/src/Compilers/Core/Portable/Compilation/Compilation.cs +++ b/src/Compilers/Core/Portable/Compilation/Compilation.cs @@ -2668,5 +2668,44 @@ internal bool IsTypeMissing(WellKnownType type) } internal abstract bool IsIOperationFeatureEnabled(); + + /// + /// Given a reporting unreferenced s, returns + /// the actual instances that were not referenced. + /// + public ImmutableArray GetUnreferencedAssemblyIdentities(Diagnostic diagnostic) + { + if (diagnostic == null) + { + throw new ArgumentNullException(nameof(diagnostic)); + } + + if (UnreferencedAssemblyIdentityDiagnosticCodes.Contains(diagnostic.Code)) + { + return ExtractAssemblyIdenties(diagnostic); + } + + return ImmutableArray.Empty; + } + + /// + /// For testing purposes. + /// + internal abstract ImmutableArray UnreferencedAssemblyIdentityDiagnosticCodes { get; } + + internal static ImmutableArray ExtractAssemblyIdenties(Diagnostic diagnostic) + { + var builder = ArrayBuilder.GetInstance(); + + foreach (var argument in diagnostic.Arguments) + { + if (argument is AssemblyIdentity id) + { + builder.Add(id); + } + } + + return builder.ToImmutableAndFree(); + } } } \ No newline at end of file diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index b1489c39400..8b2783f57aa 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -15,6 +15,7 @@ Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(Microsoft.CodeAnalysis. Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(System.Collections.Immutable.ImmutableArray elementTypes, System.Collections.Immutable.ImmutableArray elementNames = default(System.Collections.Immutable.ImmutableArray), System.Collections.Immutable.ImmutableArray elementLocations = default(System.Collections.Immutable.ImmutableArray)) -> Microsoft.CodeAnalysis.INamedTypeSymbol Microsoft.CodeAnalysis.Compilation.Emit(System.IO.Stream peStream, System.IO.Stream pdbStream = null, System.IO.Stream xmlDocumentationStream = null, System.IO.Stream win32Resources = null, System.Collections.Generic.IEnumerable manifestResources = null, Microsoft.CodeAnalysis.Emit.EmitOptions options = null, Microsoft.CodeAnalysis.IMethodSymbol debugEntryPoint = null, System.IO.Stream sourceLinkStream = null, System.Collections.Generic.IEnumerable embeddedTexts = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.Emit.EmitResult Microsoft.CodeAnalysis.Compilation.Emit(System.IO.Stream peStream, System.IO.Stream pdbStream, System.IO.Stream xmlDocumentationStream, System.IO.Stream win32Resources, System.Collections.Generic.IEnumerable manifestResources, Microsoft.CodeAnalysis.Emit.EmitOptions options, Microsoft.CodeAnalysis.IMethodSymbol debugEntryPoint, System.Threading.CancellationToken cancellationToken) -> Microsoft.CodeAnalysis.Emit.EmitResult +Microsoft.CodeAnalysis.Compilation.GetUnreferencedAssemblyIdentities(Microsoft.CodeAnalysis.Diagnostic diagnostic) -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.CompilationOptions.WithConcurrentBuild(bool concurrent) -> Microsoft.CodeAnalysis.CompilationOptions Microsoft.CodeAnalysis.CompilationOptions.WithCryptoKeyContainer(string cryptoKeyContainer) -> Microsoft.CodeAnalysis.CompilationOptions Microsoft.CodeAnalysis.CompilationOptions.WithCryptoKeyFile(string cryptoKeyFile) -> Microsoft.CodeAnalysis.CompilationOptions diff --git a/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb b/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb index d4b633295f9..c9aba69829d 100644 --- a/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb +++ b/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb @@ -2702,6 +2702,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return If(IOperationFeatureFlag Is Nothing, False, options.Features.ContainsKey(IOperationFeatureFlag)) End Function + + Friend Overrides ReadOnly Property UnreferencedAssemblyIdentityDiagnosticCodes As ImmutableArray(Of Integer) = + ImmutableArray.Create(Of Integer)( + ERRID.ERR_UnreferencedAssemblyEvent3, + ERRID.ERR_UnreferencedModuleBase3, + ERRID.ERR_UnreferencedModuleImplements3, + ERRID.ERR_UnreferencedAssembly3) + #End Region Private Class SymbolSearcher diff --git a/src/Test/Utilities/Shared/Diagnostics/DiagnosticExtensions.cs b/src/Test/Utilities/Shared/Diagnostics/DiagnosticExtensions.cs index ff080aff3b6..03f7e5acba0 100644 --- a/src/Test/Utilities/Shared/Diagnostics/DiagnosticExtensions.cs +++ b/src/Test/Utilities/Shared/Diagnostics/DiagnosticExtensions.cs @@ -97,6 +97,19 @@ public static TCompilation VerifyDiagnostics(this TCompilation c, { var diagnostics = c.GetDiagnostics(); diagnostics.Verify(expected); + + // At this point we've verified that the expected and actual diagnostics are the same. + var unreferencedAssemblyDiagnosticIds = c.UnreferencedAssemblyIdentityDiagnosticCodes; + foreach (var diagnostic in diagnostics) + { + if (unreferencedAssemblyDiagnosticIds.Contains(diagnostic.Code)) + { + // Ensure that this diagnostic contains at least one assembly id. + var assemblyIds = c.GetUnreferencedAssemblyIdentities(diagnostic); + Assert.True(assemblyIds.Length > 0); + } + } + return c; } -- GitLab