diff --git a/src/Features/Core/Portable/EditAndContinue/EditSession.cs b/src/Features/Core/Portable/EditAndContinue/EditSession.cs index df9394c7f4a4b..4ee28058383d9 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditSession.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditSession.cs @@ -1353,16 +1353,12 @@ void UpdateChangedDocumentsStaleness(bool isStale) Telemetry.LogEmitDifferenceTime(emitDifferenceTimer.Elapsed); } - // TODO: https://github.com/dotnet/roslyn/issues/36061 - // We should only report diagnostics from emit phase. - // Syntax and semantic diagnostics are already reported by the diagnostic analyzer. - // Currently we do not have means to distinguish between diagnostics reported from compilation and emit phases. - // Querying diagnostics of the entire compilation or just the updated files migth be slow. - // In fact, it is desirable to allow emitting deltas for symbols affected by the change while allowing untouched - // method bodies to have errors. - if (!emitResult.Diagnostics.IsEmpty) + foreach (var emitDiagnostic in emitResult.Diagnostics) { - projectDiagnostics.AddRange(emitResult.Diagnostics); + if (emitDiagnostic.Severity is DiagnosticSeverity.Error or DiagnosticSeverity.Warning) + { + projectDiagnostics.Add(emitDiagnostic); + } } if (!emitResult.Success) diff --git a/src/Features/ExternalAccess/HotReload/Api/HotReloadService.cs b/src/Features/ExternalAccess/HotReload/Api/HotReloadService.cs index da8d623383977..17e362e6af6c7 100644 --- a/src/Features/ExternalAccess/HotReload/Api/HotReloadService.cs +++ b/src/Features/ExternalAccess/HotReload/Api/HotReloadService.cs @@ -136,7 +136,7 @@ public readonly struct Updates private DebuggingSessionId _sessionId; public HotReloadService(HostWorkspaceServices services, ImmutableArray capabilities) - : this(services.SolutionServices, () => ValueTask.FromResult(AddImplicitDotNetCapabilities(capabilities))) + : this(services.SolutionServices, () => ValueTask.FromResult(capabilities)) { } @@ -147,13 +147,6 @@ private DebuggingSessionId GetDebuggingSession() return sessionId; } - /// - /// Adds capabilities that are available by default on runtimes supported by dotnet-watch: .NET and Mono - /// and not on .NET Framework (they are not in . - /// - private static ImmutableArray AddImplicitDotNetCapabilities(ImmutableArray capabilities) - => capabilities.Add(nameof(EditAndContinueCapabilities.AddExplicitInterfaceImplementation)); - /// /// Starts the watcher. /// diff --git a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs index 61914cfd87225..e1320aab6463d 100644 --- a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs +++ b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs @@ -2075,23 +2075,43 @@ public async Task SyntaxError() } [Fact] - public async Task SemanticError() + public async Task SemanticDiagnostics() { - var sourceV1 = "class C1 { void M() { System.Console.WriteLine(1); } }"; + var sourceV1 = """ + class C1 { void M() { System.Console.WriteLine(1); } } + """; + + var sourceV2 = """ + global using System; + using System; + + class C1 { void M() { int i = 0L; System.Console.WriteLine(i); } } + """; + + var globalUsings = """ + global using System; + """; + + var sourceFile = Temp.CreateFile("a.cs").WriteAllText(sourceV1, Encoding.UTF8); + var globalUsingsFile = Temp.CreateFile("global.cs").WriteAllText(globalUsings, Encoding.UTF8); using var _ = CreateWorkspace(out var solution, out var service); - (solution, var document) = AddDefaultTestProject(solution, sourceV1); - var moduleId = EmitAndLoadLibraryToDebuggee(document.Project.Id, sourceV1); + solution = solution. + AddTestProject("test", out var projectId). + AddTestDocument(sourceV1, sourceFile.Path, out var documentId).Project. + AddTestDocument(globalUsings, globalUsingsFile.Path).Project.Solution; + + var moduleId = EmitAndLoadLibraryToDebuggee(projectId, sourceV1); var debuggingSession = StartDebuggingSession(service, solution); EnterBreakState(debuggingSession); // change the source (compilation error): - var document1 = solution.Projects.Single().Documents.Single(); - solution = solution.WithDocumentText(document1.Id, CreateText("class C1 { void M() { int i = 0L; System.Console.WriteLine(i); } }")); - var document2 = solution.Projects.Single().Documents.Single(); + var document1 = solution.GetRequiredDocument(documentId); + solution = solution.WithDocumentText(document1.Id, CreateText(sourceV2)); + var document2 = solution.GetRequiredDocument(documentId); // compilation errors are not reported via EnC diagnostic analyzer: var diagnostics1 = await service.GetDocumentDiagnosticsAsync(document2, s_noActiveSpans, CancellationToken.None); @@ -2103,10 +2123,13 @@ public async Task SemanticError() Assert.Equal(ModuleUpdateStatus.Blocked, results.ModuleUpdates.Status); Assert.Empty(results.ModuleUpdates.Updates); - // TODO: https://github.com/dotnet/roslyn/issues/36061 - // Semantic errors should not be reported in emit diagnostics. - - AssertEx.Equal([$"proj: {document2.FilePath}: (0,30)-(0,32): Error CS0266: {string.Format(CSharpResources.ERR_NoImplicitConvCast, "long", "int")}"], InspectDiagnostics(results.Diagnostics)); + // Only errors and warnings are reported: + AssertEx.Equal( + [ + $"test: {document2.FilePath}: (1,6)-(1,12): Warning CS0105: {string.Format(CSharpResources.WRN_DuplicateUsing, "System")}", + $"test: {document2.FilePath}: (3,30)-(3,32): Error CS0266: {string.Format(CSharpResources.ERR_NoImplicitConvCast, "long", "int")}", + // Not reported: Hidden CS8933: The using directive for 'System' appeared previously as global using + ], InspectDiagnostics(results.Diagnostics)); EndDebuggingSession(debuggingSession);