diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs index 614b164e4764abaa3f3be56046e0d49710552ad8..7f15438e731dcbd015007aed11bb95f3ab0eb5a1 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs @@ -1733,6 +1733,11 @@ internal override void ReportUnusedImports(SyntaxTree filterTree, DiagnosticBag } } + CompleteTrees(filterTree); + } + + internal override void CompleteTrees(SyntaxTree filterTree) + { // By definition, a tree is complete when all of its compiler diagnostics have been reported. // Since unused imports are the last thing we compute and report, a tree is complete when // the unused imports have been reported. diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs index b09cde3aff99a58758b5a6bd32d179489cde637d..901f2b4cbb4a86df0dbe4ab2b2d080d8335b99ea 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs +++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs @@ -7729,12 +7729,13 @@ public void NoWarnAndWarnAsError_InfoDiagnostic() return output; } + [WorkItem(11368, "https://github.com/dotnet/roslyn/issues/11368")] [WorkItem(899050, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/899050")] [WorkItem(981677, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/981677")] [WorkItem(998069, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/998069")] [WorkItem(998724, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/998724")] [WorkItem(1021115, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1021115")] - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/11368")] + [Fact] public void NoWarnAndWarnAsError_WarningDiagnostic() { // This assembly has a WarningDiagnosticAnalyzer type which should produce custom warning diff --git a/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs b/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs index 0eb31c78104b97b3a9d9e3ebf4a37a44d07ea07b..a715e6893f0d618ed85c87323c245711d6864083 100644 --- a/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs +++ b/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs @@ -501,12 +501,15 @@ private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancellat win32ResourceStreamOpt, diagnosticBag, cancellationToken); + } - if (success) - { - compilation.ReportUnusedImports(null, diagnosticBag, cancellationToken); - } + // only report unused usings if we have success. + if (success) + { + compilation.ReportUnusedImports(null, diagnosticBag, cancellationToken); } + + compilation.CompleteTrees(null); } } diff --git a/src/Compilers/Core/Portable/Compilation/Compilation.cs b/src/Compilers/Core/Portable/Compilation/Compilation.cs index c329b9a1a0d854e7489ae0e46d028eb373749a40..a45e6dca580696ca4067d3577a5eb464839ecab1 100644 --- a/src/Compilers/Core/Portable/Compilation/Compilation.cs +++ b/src/Compilers/Core/Portable/Compilation/Compilation.cs @@ -1480,11 +1480,25 @@ internal bool IsRealSigned DiagnosticBag diagnostics, CancellationToken cancellationToken); + /// + /// Reports all unused imports/usings so far (and thus it must be called as a last step of Emit) + /// internal abstract void ReportUnusedImports( SyntaxTree filterTree, DiagnosticBag diagnostics, CancellationToken cancellationToken); + /// + /// Signals the event queue, if any, that we are done compiling. + /// There should not be more compiling actions after this step. + /// NOTE: once we signal about completion to analyzers they will cancel and thus in some cases we + /// may be effectively cutting off some diagnostics. + /// It is not clear if behavior is desirable. + /// See: https://github.com/dotnet/roslyn/issues/11470 + /// + /// What tree to complete. null means complete all trees. + internal abstract void CompleteTrees(SyntaxTree filterTree); + internal bool Compile( CommonPEModuleBuilder moduleBuilder, bool emittingPdb, @@ -1695,7 +1709,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken) { ReportUnusedImports(null, diagnostics, cancellationToken); } - } + } } finally { diff --git a/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb b/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb index 130325323c2c4d9ca2907d761e2d1970860f0c3b..91c315d9b9a897021011856286a5029fc9a078ff 100644 --- a/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb +++ b/src/Compilers/VisualBasic/Portable/Compilation/VisualBasicCompilation.vb @@ -1610,6 +1610,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If End If + CompleteTrees(filterTree) + End Sub + + Friend Overrides Sub CompleteTrees(filterTree As SyntaxTree) ' By definition, a tree Is complete when all of its compiler diagnostics have been reported. ' Since unused imports are the last thing we compute And report, a tree Is complete when ' the unused imports have been reported.