diff --git a/eng/Directory.Packages.props b/eng/Directory.Packages.props
index 8b0c5a473de71..50cb2e3b2cb15 100644
--- a/eng/Directory.Packages.props
+++ b/eng/Directory.Packages.props
@@ -117,7 +117,7 @@
-
+
diff --git a/src/EditorFeatures/Core/EditAndContinue/Contracts/ContractWrappers.cs b/src/EditorFeatures/Core/EditAndContinue/Contracts/ContractWrappers.cs
index 5118e11a7d526..872b044c6ed80 100644
--- a/src/EditorFeatures/Core/EditAndContinue/Contracts/ContractWrappers.cs
+++ b/src/EditorFeatures/Core/EditAndContinue/Contracts/ContractWrappers.cs
@@ -2,7 +2,9 @@
// 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.Collections.Generic;
using System.Collections.Immutable;
+using System.Linq;
using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue;
using Microsoft.VisualStudio.Debugger.Contracts.HotReload;
using InternalContracts = Microsoft.CodeAnalysis.Contracts.EditAndContinue;
@@ -23,6 +25,12 @@ public static InternalContracts.ManagedMethodId ToContract(this ManagedMethodId
public static InternalContracts.SourceSpan ToContract(this SourceSpan id)
=> new(id.StartLine, id.StartColumn, id.EndLine, id.EndColumn);
+ public static InternalContracts.ProjectInstanceId ToContract(this ProjectInstanceId id)
+ => new(id.ProjectFilePath, id.TargetFramework);
+
+ public static InternalContracts.RunningProjectInfo ToContract(this RunningProjectInfo id)
+ => new(id.ProjectInstanceId.ToContract(), id.RestartAutomatically);
+
public static InternalContracts.ManagedHotReloadAvailability ToContract(this ManagedHotReloadAvailability value)
=> new((InternalContracts.ManagedHotReloadAvailabilityStatus)value.Status, value.LocalizedMessage);
@@ -41,7 +49,7 @@ public static ManagedHotReloadUpdate FromContract(this InternalContracts.Managed
exceptionRegions: update.ExceptionRegions.SelectAsArray(FromContract));
public static ManagedHotReloadUpdates FromContract(this InternalContracts.ManagedHotReloadUpdates updates)
- => new(updates.Updates.FromContract(), updates.Diagnostics.FromContract(), updates.ProjectsToRebuild, updates.ProjectsToRestart);
+ => new(updates.Updates.FromContract(), updates.Diagnostics.FromContract(), updates.ProjectsToRebuild.SelectAsArray(FromContract), updates.ProjectsToRestart.SelectAsArray(FromContract));
public static ImmutableArray FromContract(this ImmutableArray diagnostics)
=> diagnostics.SelectAsArray(FromContract);
@@ -61,6 +69,9 @@ public static ManagedModuleMethodId FromContract(this InternalContracts.ManagedM
public static SourceSpan FromContract(this InternalContracts.SourceSpan id)
=> new(id.StartLine, id.StartColumn, id.EndLine, id.EndColumn);
+ public static ProjectInstanceId FromContract(this InternalContracts.ProjectInstanceId id)
+ => new(id.ProjectFilePath, id.TargetFramework);
+
public static ManagedExceptionRegionUpdate FromContract(this InternalContracts.ManagedExceptionRegionUpdate update)
=> new(FromContract(update.Method), update.Delta, FromContract(update.NewSpan));
diff --git a/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageService.cs b/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageService.cs
index 81115532f4766..f08f3aa82a796 100644
--- a/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageService.cs
+++ b/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageService.cs
@@ -21,8 +21,7 @@
namespace Microsoft.CodeAnalysis.EditAndContinue;
[Shared]
-[Export(typeof(IManagedHotReloadLanguageService))]
-[Export(typeof(IManagedHotReloadLanguageService2))]
+[Export(typeof(IManagedHotReloadLanguageService3))]
[Export(typeof(IEditAndContinueSolutionProvider))]
[Export(typeof(EditAndContinueLanguageService))]
[ExportMetadata("UIContext", EditAndContinueUIContext.EncCapableProjectExistsInWorkspaceUIContextString)]
@@ -34,7 +33,7 @@ internal sealed class EditAndContinueLanguageService(
Lazy debuggerService,
PdbMatchingSourceTextProvider sourceTextProvider,
IEditAndContinueLogReporter logReporter,
- IDiagnosticsRefresher diagnosticRefresher) : IManagedHotReloadLanguageService2, IEditAndContinueSolutionProvider
+ IDiagnosticsRefresher diagnosticRefresher) : IManagedHotReloadLanguageService3
{
private sealed class NoSessionException : InvalidOperationException
{
@@ -236,59 +235,9 @@ public async ValueTask DiscardUpdatesAsync(CancellationToken cancellationToken)
}
}
- public async ValueTask UpdateBaselinesAsync(ImmutableArray projectPaths, CancellationToken cancellationToken)
- {
- if (_disabled)
- {
- return;
- }
-
- var currentDesignTimeSolution = GetCurrentDesignTimeSolution();
- var currentCompileTimeSolution = GetCurrentCompileTimeSolution(currentDesignTimeSolution);
-
- try
- {
- SolutionCommitted?.Invoke(currentDesignTimeSolution);
- }
- catch (Exception e) when (FatalError.ReportAndCatch(e))
- {
- }
-
- _committedDesignTimeSolution = currentDesignTimeSolution;
- var projectIds = GetProjectIds(projectPaths, currentCompileTimeSolution);
-
- try
- {
- await GetDebuggingSession().UpdateBaselinesAsync(currentCompileTimeSolution, projectIds, cancellationToken).ConfigureAwait(false);
- }
- catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken))
- {
- }
-
- foreach (var projectId in projectIds)
- {
- workspaceProvider.Value.Workspace.EnqueueUpdateSourceGeneratorVersion(projectId, forceRegeneration: false);
- }
- }
-
- private ImmutableArray GetProjectIds(ImmutableArray projectPaths, Solution solution)
- {
- using var _ = ArrayBuilder.GetInstance(out var projectIds);
- foreach (var path in projectPaths)
- {
- var projectId = solution.Projects.FirstOrDefault(project => project.FilePath == path)?.Id;
- if (projectId != null)
- {
- projectIds.Add(projectId);
- }
- else
- {
- logReporter.Report($"Project with path '{path}' not found in the current solution.", LogMessageSeverity.Info);
- }
- }
-
- return projectIds.ToImmutable();
- }
+ [Obsolete]
+ public ValueTask UpdateBaselinesAsync(ImmutableArray projectPaths, CancellationToken cancellationToken)
+ => throw new NotImplementedException();
public async ValueTask EndSessionAsync(CancellationToken cancellationToken)
{
@@ -359,9 +308,13 @@ public async ValueTask HasChangesAsync(string? sourceFilePath, Cancellatio
[Obsolete]
public ValueTask GetUpdatesAsync(CancellationToken cancellationToken)
- => GetUpdatesAsync(runningProjects: [], cancellationToken);
+ => throw new NotImplementedException();
- public async ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
+ [Obsolete]
+ public ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
+ => throw new NotImplementedException();
+
+ public async ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
{
if (_disabled)
{
@@ -371,22 +324,13 @@ public async ValueTask GetUpdatesAsync(ImmutableArray (info.ProjectInstanceId.ProjectFilePath, info.ProjectInstanceId.TargetFramework, info.RestartAutomatically));
- using var _ = PooledHashSet.GetInstance(out var runningProjectPaths);
- runningProjectPaths.AddAll(runningProjects);
-
- // TODO: Update once implemented: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2449700
- var runningProjectInfos = solution.Projects.Where(p => p.FilePath != null && runningProjectPaths.Contains(p.FilePath)).ToImmutableDictionary(
- keySelector: static p => p.Id,
- elementSelector: static p => new RunningProjectInfo { RestartWhenChangesHaveNoEffect = false, AllowPartialUpdate = false });
-
- var result = await GetDebuggingSession().EmitSolutionUpdateAsync(solution, runningProjectInfos, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false);
+ var result = await GetDebuggingSession().EmitSolutionUpdateAsync(solution, runningProjectOptions, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false);
switch (result.ModuleUpdates.Status)
{
- case ModuleUpdateStatus.Ready when result.ProjectsToRebuild.IsEmpty:
- // We have updates to be applied and no rude edits.
- //
+ case ModuleUpdateStatus.Ready:
// The debugger will call Commit/Discard on the solution
// based on whether the updates will be applied successfully or not.
_pendingUpdatedDesignTimeSolution = designTimeSolution;
@@ -422,10 +366,14 @@ await solution.GetDocumentAsync(diagnostic.DocumentId, includeSourceGenerated: t
return new ManagedHotReloadUpdates(
result.ModuleUpdates.Updates.FromContract(),
result.GetAllDiagnostics().FromContract(),
- GetProjectPaths(result.ProjectsToRebuild),
- GetProjectPaths(result.ProjectsToRestart.Keys));
+ ToProjectIntanceIds(result.ProjectsToRebuild),
+ ToProjectIntanceIds(result.ProjectsToRestart.Keys));
- ImmutableArray GetProjectPaths(IEnumerable ids)
- => ids.SelectAsArray(id => solution.GetRequiredProject(id).FilePath!);
+ ImmutableArray ToProjectIntanceIds(IEnumerable ids)
+ => ids.SelectAsArray(id =>
+ {
+ var project = solution.GetRequiredProject(id);
+ return new ProjectInstanceId(project.FilePath!, project.State.NameAndFlavor.flavor ?? "");
+ });
}
}
diff --git a/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageServiceBridge.cs b/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageServiceBridge.cs
index be9aadc407671..a58f500f26ddb 100644
--- a/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageServiceBridge.cs
+++ b/src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageServiceBridge.cs
@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.EditAndContinue;
/// TODO (https://github.com/dotnet/roslyn/issues/72713):
/// Once debugger is updated to use the brokered service, this class should be removed and should be exported directly.
///
-internal sealed partial class ManagedEditAndContinueLanguageServiceBridge(EditAndContinueLanguageService service) : IManagedHotReloadLanguageService2
+internal sealed partial class ManagedEditAndContinueLanguageServiceBridge(EditAndContinueLanguageService service) : IManagedHotReloadLanguageService3
{
public ValueTask StartSessionAsync(CancellationToken cancellationToken)
=> service.StartSessionAsync(cancellationToken);
@@ -34,16 +34,21 @@ public ValueTask OnCapabilitiesChangedAsync(CancellationToken cancellationToken)
[Obsolete]
public ValueTask GetUpdatesAsync(CancellationToken cancellationToken)
- => service.GetUpdatesAsync(cancellationToken);
+ => throw new NotImplementedException();
+ [Obsolete]
public ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
+ => throw new NotImplementedException();
+
+ public ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
=> service.GetUpdatesAsync(runningProjects, cancellationToken);
public ValueTask CommitUpdatesAsync(CancellationToken cancellationToken)
=> service.CommitUpdatesAsync(cancellationToken);
+ [Obsolete]
public ValueTask UpdateBaselinesAsync(ImmutableArray projectPaths, CancellationToken cancellationToken)
- => service.UpdateBaselinesAsync(projectPaths, cancellationToken);
+ => throw new NotImplementedException();
public ValueTask DiscardUpdatesAsync(CancellationToken cancellationToken)
=> service.DiscardUpdatesAsync(cancellationToken);
diff --git a/src/EditorFeatures/ExternalAccess/Debugger/GlassTestsHotReloadService.cs b/src/EditorFeatures/ExternalAccess/Debugger/GlassTestsHotReloadService.cs
index d8b299ea817ca..fb5981590e18c 100644
--- a/src/EditorFeatures/ExternalAccess/Debugger/GlassTestsHotReloadService.cs
+++ b/src/EditorFeatures/ExternalAccess/Debugger/GlassTestsHotReloadService.cs
@@ -84,7 +84,7 @@ public void EndDebuggingSession()
public async ValueTask GetUpdatesAsync(Solution solution, CancellationToken cancellationToken)
{
- var results = (await _encService.EmitSolutionUpdateAsync(GetSessionId(), solution, runningProjects: ImmutableDictionary.Empty, s_noActiveStatementSpanProvider, cancellationToken).ConfigureAwait(false)).Dehydrate();
- return new ManagedHotReloadUpdates(results.ModuleUpdates.Updates.FromContract(), results.GetAllDiagnostics().FromContract(), [], []);
+ var results = (await _encService.EmitSolutionUpdateAsync(GetSessionId(), solution, runningProjects: ImmutableDictionary.Empty, s_noActiveStatementSpanProvider, cancellationToken).ConfigureAwait(false)).Dehydrate();
+ return new ManagedHotReloadUpdates(results.ModuleUpdates.Updates.FromContract(), results.GetAllDiagnostics().FromContract(), projectInstancesToRebuild: [], projectInstancesToRestart: []);
}
}
diff --git a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs
index 389c8beb70085..f4f2baa187b5b 100644
--- a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs
+++ b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs
@@ -216,7 +216,13 @@ await localWorkspace.ChangeSolutionAsync(localWorkspace.CurrentSolution
};
};
- var updates = await localService.GetUpdatesAsync(runningProjects: [project.FilePath], CancellationToken.None);
+ var runningProjectInfo = new DebuggerContracts.RunningProjectInfo()
+ {
+ ProjectInstanceId = new DebuggerContracts.ProjectInstanceId(project.FilePath, "net9.0"),
+ RestartAutomatically = false,
+ };
+
+ var updates = await localService.GetUpdatesAsync(runningProjects: [runningProjectInfo], CancellationToken.None);
Assert.Equal(++observedDiagnosticVersion, diagnosticRefresher.GlobalStateVersion);
@@ -281,7 +287,7 @@ await localWorkspace.ChangeSolutionAsync(localWorkspace.CurrentSolution
};
};
- updates = await localService.GetUpdatesAsync(runningProjects: [project.FilePath], CancellationToken.None);
+ updates = await localService.GetUpdatesAsync(runningProjects: [runningProjectInfo], CancellationToken.None);
Assert.Equal(++observedDiagnosticVersion, diagnosticRefresher.GlobalStateVersion);
diff --git a/src/Features/Core/Portable/Contracts/EditAndContinue/IManagedHotReloadLanguageService.cs b/src/Features/Core/Portable/Contracts/EditAndContinue/IManagedHotReloadLanguageService.cs
index 3ca98a0430989..0e4d61e6ac6ab 100644
--- a/src/Features/Core/Portable/Contracts/EditAndContinue/IManagedHotReloadLanguageService.cs
+++ b/src/Features/Core/Portable/Contracts/EditAndContinue/IManagedHotReloadLanguageService.cs
@@ -2,6 +2,7 @@
// 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;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
@@ -15,6 +16,7 @@ internal interface IManagedHotReloadLanguageService
ValueTask EndSessionAsync(CancellationToken cancellationToken);
ValueTask EnterBreakStateAsync(CancellationToken cancellationToken);
ValueTask ExitBreakStateAsync(CancellationToken cancellationToken);
+ [Obsolete]
ValueTask GetUpdatesAsync(CancellationToken cancellationToken);
ValueTask HasChangesAsync(string? sourceFilePath, CancellationToken cancellationToken);
ValueTask OnCapabilitiesChangedAsync(CancellationToken cancellationToken);
@@ -23,6 +25,14 @@ internal interface IManagedHotReloadLanguageService
internal interface IManagedHotReloadLanguageService2 : IManagedHotReloadLanguageService
{
+ [Obsolete]
ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken);
+
+ [Obsolete]
ValueTask UpdateBaselinesAsync(ImmutableArray projectPaths, CancellationToken cancellationToken);
}
+
+internal interface IManagedHotReloadLanguageService3 : IManagedHotReloadLanguageService2
+{
+ ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken);
+}
diff --git a/src/Features/Core/Portable/Contracts/EditAndContinue/ManagedHotReloadUpdates.cs b/src/Features/Core/Portable/Contracts/EditAndContinue/ManagedHotReloadUpdates.cs
index 7fd7b7e09c751..e8f0b167f8815 100644
--- a/src/Features/Core/Portable/Contracts/EditAndContinue/ManagedHotReloadUpdates.cs
+++ b/src/Features/Core/Portable/Contracts/EditAndContinue/ManagedHotReloadUpdates.cs
@@ -8,7 +8,7 @@
namespace Microsoft.CodeAnalysis.Contracts.EditAndContinue;
[DataContract]
-internal readonly struct ManagedHotReloadUpdates(ImmutableArray updates, ImmutableArray diagnostics, ImmutableArray projectsToRebuild, ImmutableArray projectsToRestart)
+internal readonly struct ManagedHotReloadUpdates(ImmutableArray updates, ImmutableArray diagnostics, ImmutableArray projectsToRebuild, ImmutableArray projectsToRestart)
{
[DataMember(Name = "updates")]
public ImmutableArray Updates { get; } = updates;
@@ -17,8 +17,8 @@ internal readonly struct ManagedHotReloadUpdates(ImmutableArray Diagnostics { get; } = diagnostics;
[DataMember(Name = "projectsToRebuild")]
- public ImmutableArray ProjectsToRebuild { get; } = projectsToRebuild;
+ public ImmutableArray ProjectsToRebuild { get; } = projectsToRebuild;
[DataMember(Name = "projectsToRestart")]
- public ImmutableArray ProjectsToRestart { get; } = projectsToRestart;
+ public ImmutableArray ProjectsToRestart { get; } = projectsToRestart;
}
diff --git a/src/Features/Core/Portable/Contracts/EditAndContinue/ProjectInstanceId.cs b/src/Features/Core/Portable/Contracts/EditAndContinue/ProjectInstanceId.cs
new file mode 100644
index 0000000000000..2797481f7cb1b
--- /dev/null
+++ b/src/Features/Core/Portable/Contracts/EditAndContinue/ProjectInstanceId.cs
@@ -0,0 +1,17 @@
+// 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.Runtime.Serialization;
+
+namespace Microsoft.CodeAnalysis.Contracts.EditAndContinue;
+
+[DataContract]
+internal readonly struct ProjectInstanceId(string projectFilePath, string targetFramework)
+{
+ [DataMember(Name = "projectFilePath")]
+ public string ProjectFilePath { get; } = projectFilePath;
+
+ [DataMember(Name = "targetFramework")]
+ public string TargetFramework { get; } = targetFramework;
+}
diff --git a/src/Features/Core/Portable/Contracts/EditAndContinue/RunningProjectInfo.cs b/src/Features/Core/Portable/Contracts/EditAndContinue/RunningProjectInfo.cs
new file mode 100644
index 0000000000000..9e11ee9dbd9c8
--- /dev/null
+++ b/src/Features/Core/Portable/Contracts/EditAndContinue/RunningProjectInfo.cs
@@ -0,0 +1,17 @@
+// 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.Runtime.Serialization;
+
+namespace Microsoft.CodeAnalysis.Contracts.EditAndContinue;
+
+[DataContract]
+internal readonly struct RunningProjectInfo(ProjectInstanceId projectInstanceId, bool restartAutomatically)
+{
+ [DataMember(Name = "projectInstanceId")]
+ public ProjectInstanceId ProjectInstanceId { get; } = projectInstanceId;
+
+ [DataMember(Name = "restartAutomatically")]
+ public bool RestartAutomatically { get; } = restartAutomatically;
+}
diff --git a/src/Features/Core/Portable/EditAndContinue/CommittedSolution.cs b/src/Features/Core/Portable/EditAndContinue/CommittedSolution.cs
index e73d4cea23cd6..76408ddc1a5fd 100644
--- a/src/Features/Core/Portable/EditAndContinue/CommittedSolution.cs
+++ b/src/Features/Core/Portable/EditAndContinue/CommittedSolution.cs
@@ -455,16 +455,12 @@ await TryGetMatchingSourceTextAsync(log, sourceText, sourceFilePath, currentDocu
}
}
- public void CommitChanges(Solution solution, ImmutableDictionary? staleProjects, ImmutableArray? projectsToUnstale = null)
+ public void CommitChanges(Solution solution, ImmutableDictionary staleProjects)
{
- Contract.ThrowIfTrue(staleProjects is null && projectsToUnstale is null);
-
lock (_guard)
{
_solution = solution;
- staleProjects ??= _staleProjects.RemoveRange(projectsToUnstale!);
-
var oldStaleProjects = _staleProjects;
_staleProjects = staleProjects;
diff --git a/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs b/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs
index 64f8410edf233..251c5220aa989 100644
--- a/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs
+++ b/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs
@@ -523,7 +523,7 @@ CommittedSolution.DocumentState.Indeterminate or
public async ValueTask EmitSolutionUpdateAsync(
Solution solution,
- ImmutableDictionary runningProjects,
+ ImmutableDictionary runningProjects,
ActiveStatementSpanProvider activeStatementSpanProvider,
CancellationToken cancellationToken)
{
@@ -536,8 +536,6 @@ public async ValueTask EmitSolutionUpdateAsync(
var solutionUpdate = await EditSession.EmitSolutionUpdateAsync(solution, activeStatementSpanProvider, updateId, runningProjects, cancellationToken).ConfigureAwait(false);
- var allowPartialUpdates = runningProjects.Any(p => p.Value.AllowPartialUpdate);
-
solutionUpdate.Log(SessionLog, updateId);
_lastModuleUpdatesLog = solutionUpdate.ModuleUpdates.Updates;
@@ -549,29 +547,13 @@ public async ValueTask EmitSolutionUpdateAsync(
// We have updates to be applied or processes to restart. The debugger will call Commit/Discard on the solution
// based on whether the updates will be applied successfully or not.
- if (allowPartialUpdates)
- {
- StorePendingUpdate(new PendingSolutionUpdate(
- solution,
- solutionUpdate.StaleProjects,
- solutionUpdate.ProjectsToRebuild,
- solutionUpdate.ProjectBaselines,
- solutionUpdate.ModuleUpdates.Updates,
- solutionUpdate.NonRemappableRegions));
- }
- else if (solutionUpdate.ProjectsToRebuild.IsEmpty)
- {
- // no rude edits
-
- StorePendingUpdate(new PendingSolutionUpdate(
- solution,
- solutionUpdate.StaleProjects,
- // if partial updates are not allowed we don't treat rebuild as part of solution update:
- projectsToRebuild: [],
- solutionUpdate.ProjectBaselines,
- solutionUpdate.ModuleUpdates.Updates,
- solutionUpdate.NonRemappableRegions));
- }
+ StorePendingUpdate(new PendingSolutionUpdate(
+ solution,
+ solutionUpdate.StaleProjects,
+ solutionUpdate.ProjectsToRebuild,
+ solutionUpdate.ProjectBaselines,
+ solutionUpdate.ModuleUpdates.Updates,
+ solutionUpdate.NonRemappableRegions));
break;
@@ -594,10 +576,7 @@ public async ValueTask EmitSolutionUpdateAsync(
return new EmitSolutionUpdateResults()
{
Solution = solution,
- // If partial updates are disabled the debugger does not expect module updates when rude edits are reported:
- ModuleUpdates = allowPartialUpdates || solutionUpdate.ProjectsToRebuild.IsEmpty
- ? solutionUpdate.ModuleUpdates
- : new ModuleUpdates(solutionUpdate.ModuleUpdates.Status, []),
+ ModuleUpdates = solutionUpdate.ModuleUpdates,
Diagnostics = solutionUpdate.Diagnostics,
SyntaxError = solutionUpdate.SyntaxError,
ProjectsToRestart = solutionUpdate.ProjectsToRestart,
@@ -704,36 +683,6 @@ private void DiscardProjectBaselinesNoLock(Solution solution, IEnumerable rebuiltProjects)
- {
- ThrowIfDisposed();
-
- // Make sure the solution snapshot has all source-generated documents up-to-date.
- solution = solution.WithUpToDateSourceGeneratorDocuments(solution.ProjectIds);
-
- LastCommittedSolution.CommitChanges(solution, staleProjects: null, projectsToUnstale: rebuiltProjects);
-
- // Wait for all operations on baseline to finish before we dispose the readers.
-
- _baselineContentAccessLock.EnterWriteLock();
-
- lock (_projectEmitBaselinesGuard)
- {
- DiscardProjectBaselinesNoLock(solution, rebuiltProjects);
- }
-
- _baselineContentAccessLock.ExitWriteLock();
-
- foreach (var projectId in rebuiltProjects)
- {
- _editSessionTelemetry.LogUpdatedBaseline(solution.GetRequiredProject(projectId).State.ProjectInfo.Attributes.TelemetryId);
- }
-
- // Restart edit session reusing previous non-remappable regions and break state:
- RestartEditSession(nonRemappableRegions: null, inBreakState: null);
- }
-
///
/// Returns s for each document of ,
/// or default if not in a break state.
diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueService.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueService.cs
index a27aaaa5141a3..029f020263026 100644
--- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueService.cs
+++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueService.cs
@@ -220,7 +220,7 @@ public ValueTask> GetDocumentDiagnosticsAsync(Documen
public ValueTask EmitSolutionUpdateAsync(
DebuggingSessionId sessionId,
Solution solution,
- ImmutableDictionary runningProjects,
+ ImmutableDictionary runningProjects,
ActiveStatementSpanProvider activeStatementSpanProvider,
CancellationToken cancellationToken)
{
@@ -249,14 +249,6 @@ public void DiscardSolutionUpdate(DebuggingSessionId sessionId)
debuggingSession.DiscardSolutionUpdate();
}
- public void UpdateBaselines(DebuggingSessionId sessionId, Solution solution, ImmutableArray rebuiltProjects)
- {
- var debuggingSession = TryGetDebuggingSession(sessionId);
- Contract.ThrowIfNull(debuggingSession);
-
- debuggingSession.UpdateBaselines(solution, rebuiltProjects);
- }
-
public ValueTask>> GetBaseActiveStatementSpansAsync(DebuggingSessionId sessionId, Solution solution, ImmutableArray documentIds, CancellationToken cancellationToken)
{
var debuggingSession = TryGetDebuggingSession(sessionId);
diff --git a/src/Features/Core/Portable/EditAndContinue/EditSession.cs b/src/Features/Core/Portable/EditAndContinue/EditSession.cs
index 11c4f4b7895e9..03ff251d0d2ff 100644
--- a/src/Features/Core/Portable/EditAndContinue/EditSession.cs
+++ b/src/Features/Core/Portable/EditAndContinue/EditSession.cs
@@ -957,7 +957,7 @@ public async ValueTask EmitSolutionUpdateAsync(
Solution solution,
ActiveStatementSpanProvider solutionActiveStatementSpanProvider,
UpdateId updateId,
- ImmutableDictionary runningProjects,
+ ImmutableDictionary runningProjects,
CancellationToken cancellationToken)
{
var projectDiagnostics = ArrayBuilder.GetInstance();
diff --git a/src/Features/Core/Portable/EditAndContinue/EmitSolutionUpdateResults.cs b/src/Features/Core/Portable/EditAndContinue/EmitSolutionUpdateResults.cs
index 8cbcc14f815f2..e4ae6e69d3cd9 100644
--- a/src/Features/Core/Portable/EditAndContinue/EmitSolutionUpdateResults.cs
+++ b/src/Features/Core/Portable/EditAndContinue/EmitSolutionUpdateResults.cs
@@ -78,7 +78,7 @@ internal ImmutableArray GetAllDiagnostics()
return builder.ToImmutableAndClear();
}
- public static Data CreateFromInternalError(Solution solution, string errorMessage, ImmutableDictionary runningProjects)
+ public static Data CreateFromInternalError(Solution solution, string errorMessage, ImmutableDictionary runningProjects)
{
ImmutableArray diagnostics = [];
var firstProject = solution.GetProject(runningProjects.FirstOrDefault().Key) ?? solution.Projects.First();
@@ -200,7 +200,7 @@ internal static void GetProjectsToRebuildAndRestart(
ImmutableArray moduleUpdates,
ImmutableArray diagnostics,
IReadOnlyCollection addedUnbuiltProjects,
- ImmutableDictionary runningProjects,
+ ImmutableDictionary runningProjects,
out ImmutableDictionary> projectsToRestart,
out ImmutableArray projectsToRebuild)
{
@@ -279,26 +279,7 @@ internal static void GetProjectsToRebuildAndRestart(
// At this point the restart set contains all running projects transitively affected by rude edits.
// Next, find projects that were successfully updated and affect running projects.
- // Remove once https://github.com/dotnet/roslyn/issues/78244 is implemented.
- if (!runningProjects.Any(static p => p.Value.AllowPartialUpdate))
- {
- // Partial solution update not supported.
- if (projectsToRestartBuilder.Any())
- {
- foreach (var update in moduleUpdates)
- {
- foreach (var ancestor in GetAncestorsAndSelf(update.ProjectId))
- {
- if (runningProjects.ContainsKey(ancestor))
- {
- projectsToRebuildBuilder.TryAdd(ancestor, []);
- projectsToRestartBuilder.Add(ancestor);
- }
- }
- }
- }
- }
- else if (!moduleUpdates.IsEmpty && projectsToRebuildBuilder.Count > 0)
+ if (!moduleUpdates.IsEmpty && projectsToRebuildBuilder.Count > 0)
{
// The set of updated projects is usually much smaller than the number of all projects in the solution.
// We iterate over this set updating the restart set until no new project is added to the restart set.
diff --git a/src/Features/Core/Portable/EditAndContinue/IEditAndContinueService.cs b/src/Features/Core/Portable/EditAndContinue/IEditAndContinueService.cs
index 77384c0fc39fe..46d34c03a6ae3 100644
--- a/src/Features/Core/Portable/EditAndContinue/IEditAndContinueService.cs
+++ b/src/Features/Core/Portable/EditAndContinue/IEditAndContinueService.cs
@@ -19,11 +19,10 @@ internal interface IEditAndContinueWorkspaceService : IWorkspaceService
internal interface IEditAndContinueService
{
ValueTask> GetDocumentDiagnosticsAsync(Document document, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken);
- ValueTask EmitSolutionUpdateAsync(DebuggingSessionId sessionId, Solution solution, ImmutableDictionary runningProjects, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken);
+ ValueTask EmitSolutionUpdateAsync(DebuggingSessionId sessionId, Solution solution, ImmutableDictionary runningProjects, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken);
void CommitSolutionUpdate(DebuggingSessionId sessionId);
void DiscardSolutionUpdate(DebuggingSessionId sessionId);
- void UpdateBaselines(DebuggingSessionId sessionId, Solution solution, ImmutableArray rebuiltProjects);
ValueTask StartDebuggingSessionAsync(Solution solution, IManagedHotReloadService debuggerService, IPdbMatchingSourceTextProvider sourceTextProvider, ImmutableArray captureMatchingDocuments, bool captureAllMatchingDocuments, bool reportDiagnostics, CancellationToken cancellationToken);
void BreakStateOrCapabilitiesChanged(DebuggingSessionId sessionId, bool? inBreakState);
diff --git a/src/Features/Core/Portable/EditAndContinue/ModuleUpdateStatus.cs b/src/Features/Core/Portable/EditAndContinue/ModuleUpdateStatus.cs
index 9eb9f048428cd..503303b6d5b13 100644
--- a/src/Features/Core/Portable/EditAndContinue/ModuleUpdateStatus.cs
+++ b/src/Features/Core/Portable/EditAndContinue/ModuleUpdateStatus.cs
@@ -11,17 +11,21 @@ internal enum ModuleUpdateStatus
{
///
/// No change made.
+ /// Pending solution update is not created.
+ /// Committed solution snapshot is advanced.
///
None = 0,
///
/// Changes can be applied (project might need rebuild in presence of transient errors).
+ /// A pending solution update is created and has to be committed (commited solution snapshot is advanced at that point) or discarded.
///
Ready = 1,
///
/// Some changes are errors that block rebuild of the module.
/// This means that the code is in a broken state that cannot be resolved by restarting the application.
+ /// Pending solution update is not created.
///
Blocked = 2
}
diff --git a/src/Features/Core/Portable/EditAndContinue/Remote/IRemoteEditAndContinueService.cs b/src/Features/Core/Portable/EditAndContinue/Remote/IRemoteEditAndContinueService.cs
index 5f6b14203f2e5..86232da3050b7 100644
--- a/src/Features/Core/Portable/EditAndContinue/Remote/IRemoteEditAndContinueService.cs
+++ b/src/Features/Core/Portable/EditAndContinue/Remote/IRemoteEditAndContinueService.cs
@@ -27,14 +27,13 @@ internal interface ICallback
}
ValueTask> GetDocumentDiagnosticsAsync(Checksum solutionChecksum, RemoteServiceCallbackId callbackId, DocumentId documentId, CancellationToken cancellationToken);
- ValueTask EmitSolutionUpdateAsync(Checksum solutionChecksum, RemoteServiceCallbackId callbackId, DebuggingSessionId sessionId, ImmutableDictionary runningProjects, CancellationToken cancellationToken);
+ ValueTask EmitSolutionUpdateAsync(Checksum solutionChecksum, RemoteServiceCallbackId callbackId, DebuggingSessionId sessionId, ImmutableDictionary runningProjects, CancellationToken cancellationToken);
///
/// Returns ids of documents for which diagnostics need to be refreshed in-proc.
///
ValueTask CommitSolutionUpdateAsync(DebuggingSessionId sessionId, CancellationToken cancellationToken);
ValueTask DiscardSolutionUpdateAsync(DebuggingSessionId sessionId, CancellationToken cancellationToken);
- ValueTask UpdateBaselinesAsync(Checksum solutionInfo, DebuggingSessionId sessionId, ImmutableArray rebuiltProjects, CancellationToken cancellationToken);
ValueTask StartDebuggingSessionAsync(Checksum solutionChecksum, RemoteServiceCallbackId callbackId, ImmutableArray captureMatchingDocuments, bool captureAllMatchingDocuments, bool reportDiagnostics, CancellationToken cancellationToken);
diff --git a/src/Features/Core/Portable/EditAndContinue/Remote/RemoteDebuggingSessionProxy.cs b/src/Features/Core/Portable/EditAndContinue/Remote/RemoteDebuggingSessionProxy.cs
index a460d799beef7..a789e81577fd9 100644
--- a/src/Features/Core/Portable/EditAndContinue/Remote/RemoteDebuggingSessionProxy.cs
+++ b/src/Features/Core/Portable/EditAndContinue/Remote/RemoteDebuggingSessionProxy.cs
@@ -54,7 +54,7 @@ await client.TryInvokeAsync(
public async ValueTask EmitSolutionUpdateAsync(
Solution solution,
- ImmutableDictionary runningProjects,
+ ImmutableDictionary runningProjects,
ActiveStatementSpanProvider activeStatementSpanProvider,
CancellationToken cancellationToken)
{
@@ -111,22 +111,6 @@ await client.TryInvokeAsync(
cancellationToken).ConfigureAwait(false);
}
- public async ValueTask UpdateBaselinesAsync(Solution solution, ImmutableArray rebuiltProjects, CancellationToken cancellationToken)
- {
- var client = await RemoteHostClient.TryGetClientAsync(services, cancellationToken).ConfigureAwait(false);
- if (client == null)
- {
- GetLocalService().UpdateBaselines(sessionId, solution, rebuiltProjects);
- }
- else
- {
- var result = await client.TryInvokeAsync(
- solution,
- (service, solutionInfo, cancellationToken) => service.UpdateBaselinesAsync(solutionInfo, sessionId, rebuiltProjects, cancellationToken),
- cancellationToken).ConfigureAwait(false);
- }
- }
-
public async ValueTask>> GetBaseActiveStatementSpansAsync(Solution solution, ImmutableArray documentIds, CancellationToken cancellationToken)
{
var client = await RemoteHostClient.TryGetClientAsync(services, cancellationToken).ConfigureAwait(false);
diff --git a/src/Features/Core/Portable/EditAndContinue/RunningProjectInfo.cs b/src/Features/Core/Portable/EditAndContinue/RunningProjectInfo.cs
deleted file mode 100644
index deafbf97e3e06..0000000000000
--- a/src/Features/Core/Portable/EditAndContinue/RunningProjectInfo.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.Runtime.Serialization;
-
-namespace Microsoft.CodeAnalysis.EditAndContinue;
-
-[DataContract]
-internal readonly struct RunningProjectInfo
-{
- ///
- /// Required restart of the project when an edit that has no effect until the app is restarted is made to any dependent project.
- ///
- [DataMember]
- public required bool RestartWhenChangesHaveNoEffect { get; init; }
-
- ///
- /// TODO: remove when implemented: https://github.com/dotnet/roslyn/issues/78244
- /// Indicates that the info has been passed from debugger.
- ///
- [DataMember]
- public required bool AllowPartialUpdate { get; init; }
-}
diff --git a/src/Features/Core/Portable/EditAndContinue/RunningProjectOptions.cs b/src/Features/Core/Portable/EditAndContinue/RunningProjectOptions.cs
new file mode 100644
index 0000000000000..b2839f27ecbbf
--- /dev/null
+++ b/src/Features/Core/Portable/EditAndContinue/RunningProjectOptions.cs
@@ -0,0 +1,74 @@
+// 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;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Runtime.Serialization;
+
+namespace Microsoft.CodeAnalysis.EditAndContinue;
+
+[DataContract]
+internal readonly struct RunningProjectOptions
+{
+ ///
+ /// Required restart of the project when an edit that has no effect until the app is restarted is made to any dependent project.
+ ///
+ [DataMember]
+ public required bool RestartWhenChangesHaveNoEffect { get; init; }
+}
+
+internal static class RunningProjectOptionsFactory
+{
+ public static ImmutableDictionary ToRunningProjectOptions(
+ this ImmutableArray runningProjects,
+ Solution solution,
+ Func translator)
+ {
+ // Invariants guaranteed by the debugger:
+ // - Running projects does nto contain duplicate ids.
+ // - TFM is always specified for SDK projects event if the project doesn't multi-target, it is empty for legacy projects.
+
+ var runningProjectsByPathAndTfm = runningProjects
+ .Select(info =>
+ {
+ var (filePath, targetFramework, restartAutomatically) = translator(info);
+ return KeyValuePair.Create((filePath, targetFramework is { Length: > 0 } tfm ? tfm : null), restartAutomatically);
+ })
+ .ToImmutableDictionary(PathAndTfmComparer.Instance);
+
+ var result = ImmutableDictionary.CreateBuilder();
+
+ foreach (var project in solution.Projects)
+ {
+ if (project.FilePath == null)
+ {
+ continue;
+ }
+
+ // Roslyn project name does not include TFM if the project is not multi-targeted (flavor is null).
+ // The key comparer ignores TFM if null and therefore returns a random entry that has the same file path.
+ // Since projects without TFM can only have at most one entry in the dictionary the random entry is that single value.
+ if (runningProjectsByPathAndTfm.TryGetValue((project.FilePath, project.State.NameAndFlavor.flavor), out var restartAutomatically))
+ {
+ result.Add(project.Id, new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = restartAutomatically });
+ continue;
+ }
+ }
+
+ return result.ToImmutableDictionary();
+ }
+
+ private sealed class PathAndTfmComparer : IEqualityComparer<(string path, string? tfm)>
+ {
+ public static readonly PathAndTfmComparer Instance = new();
+
+ public int GetHashCode((string path, string? tfm) obj)
+ => obj.path.GetHashCode(); // only hash path, all tfms need to fall to the same bucket
+
+ public bool Equals((string path, string? tfm) x, (string path, string? tfm) y)
+ => x.path == y.path && (x.tfm == null || y.tfm == null || x.tfm == y.tfm);
+ }
+}
diff --git a/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingHotReloadService.cs b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingHotReloadService.cs
index 89e3cb0857ac4..e46a0a1034d2a 100644
--- a/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingHotReloadService.cs
+++ b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingHotReloadService.cs
@@ -51,9 +51,6 @@ public readonly struct Update(
private static readonly ActiveStatementSpanProvider s_solutionActiveStatementSpanProvider =
(_, _, _) => ValueTask.FromResult(ImmutableArray.Empty);
- private static readonly ImmutableArray EmptyUpdate = [];
- private static readonly ImmutableArray EmptyDiagnostic = [];
-
private readonly IEditAndContinueService _encService = services.GetRequiredService().Service;
private DebuggingSessionId _sessionId;
@@ -95,10 +92,10 @@ public async Task StartSessionAsync(Solution solution, ImmutableArray ca
Contract.ThrowIfFalse(sessionId != default, "Session has not started");
var results = await _encService
- .EmitSolutionUpdateAsync(sessionId, solution, runningProjects: ImmutableDictionary.Empty, s_solutionActiveStatementSpanProvider, cancellationToken)
+ .EmitSolutionUpdateAsync(sessionId, solution, runningProjects: ImmutableDictionary.Empty, s_solutionActiveStatementSpanProvider, cancellationToken)
.ConfigureAwait(false);
- if (!results.ModuleUpdates.Updates.IsEmpty)
+ if (results.ModuleUpdates.Status == ModuleUpdateStatus.Ready)
{
if (commitUpdates)
{
@@ -110,11 +107,10 @@ public async Task StartSessionAsync(Solution solution, ImmutableArray ca
}
}
- if (results.SyntaxError is not null)
+ var diagnostics = results.GetAllDiagnostics();
+ if (diagnostics.HasAnyErrors())
{
- // We do not need to acquire any updates or other
- // diagnostics if there is a syntax error.
- return (EmptyUpdate, EmptyDiagnostic.Add(results.SyntaxError));
+ return ([], diagnostics);
}
var updates = results.ModuleUpdates.Updates.SelectAsArray(
@@ -126,8 +122,6 @@ public async Task StartSessionAsync(Solution solution, ImmutableArray ca
update.UpdatedMethods,
update.UpdatedTypes));
- var diagnostics = results.GetAllDiagnostics();
-
return (updates, diagnostics);
}
diff --git a/src/Features/Core/Portable/ExternalAccess/Watch/Api/WatchHotReloadService.cs b/src/Features/Core/Portable/ExternalAccess/Watch/Api/WatchHotReloadService.cs
index 7244152f9ef33..b19e4fc5a6b9a 100644
--- a/src/Features/Core/Portable/ExternalAccess/Watch/Api/WatchHotReloadService.cs
+++ b/src/Features/Core/Portable/ExternalAccess/Watch/Api/WatchHotReloadService.cs
@@ -191,9 +191,6 @@ public void CapabilitiesChanged()
public static string? GetTargetFramework(Project project)
=> project.State.NameAndFlavor.flavor;
- // TODO: remove, for backwards compat only
- public static bool RequireCommit { get; set; }
-
///
/// Emits updates for all projects that differ between the given snapshot and the one given to the previous successful call or
/// the one passed to for the first invocation.
@@ -211,21 +208,13 @@ public async Task GetUpdatesAsync(Solution solution, ImmutableDictiona
var runningProjectsImpl = runningProjects.ToImmutableDictionary(
static e => e.Key,
- static e => new EditAndContinue.RunningProjectInfo()
+ static e => new RunningProjectOptions()
{
- RestartWhenChangesHaveNoEffect = e.Value.RestartWhenChangesHaveNoEffect,
- AllowPartialUpdate = RequireCommit
+ RestartWhenChangesHaveNoEffect = e.Value.RestartWhenChangesHaveNoEffect
});
var results = await _encService.EmitSolutionUpdateAsync(sessionId, solution, runningProjectsImpl, s_solutionActiveStatementSpanProvider, cancellationToken).ConfigureAwait(false);
- // If the changes fail to apply dotnet-watch fails.
- // We don't support discarding the changes and letting the user retry.
- if (!RequireCommit && results.ModuleUpdates.Status is ModuleUpdateStatus.Ready && results.ProjectsToRebuild.IsEmpty)
- {
- _encService.CommitSolutionUpdate(sessionId);
- }
-
return new Updates2
{
Status = results.ModuleUpdates.Status switch
@@ -263,12 +252,6 @@ public void DiscardUpdate()
_encService.DiscardSolutionUpdate(sessionId);
}
- public void UpdateBaselines(Solution solution, ImmutableArray projectIds)
- {
- var sessionId = GetDebuggingSession();
- _encService.UpdateBaselines(sessionId, solution, projectIds);
- }
-
public void EndSession()
{
_encService.EndDebuggingSession(GetDebuggingSession());
diff --git a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs
index c3b7810df4307..b3132866960e5 100644
--- a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs
+++ b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs
@@ -152,12 +152,12 @@ public async Task StartDebuggingSession_CapturingDocuments(bool captureAllDocume
EnterBreakState(debuggingSession);
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
// TODO: warning reported https://github.com/dotnet/roslyn/issues/78125
- // AssertEx.Equal([$"P.csproj: (0,0)-(0,0): Warning ENC1005: {string.Format(FeaturesResources.DocumentIsOutOfSyncWithDebuggee, sourceFileB.Path)}"], InspectDiagnostics(emitDiagnostics));
+ // AssertEx.Equal([$"P.csproj: (0,0)-(0,0): Warning ENC1005: {string.Format(FeaturesResources.DocumentIsOutOfSyncWithDebuggee, sourceFileB.Path)}"], InspectDiagnostics(results.Diagnostics));
EndDebuggingSession(debuggingSession);
}
@@ -182,13 +182,13 @@ public async Task ProjectNotBuilt()
Assert.Empty(diagnostics);
// changes in the project are ignored:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.Equal(
[
- $"{document1.Project.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, document1.FilePath)}"
- ], InspectDiagnostics(emitDiagnostics));
+ $"proj: {document1.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, document1.FilePath)}"
+ ], InspectDiagnostics(results.Diagnostics));
EndDebuggingSession(debuggingSession);
}
@@ -219,8 +219,8 @@ public async Task DifferentDocumentWithSameContent()
Assert.Empty(diagnostics2);
// validate solution update status and emit - changes made during run mode are ignored:
- var (updates, _) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
EndDebuggingSession(debuggingSession);
@@ -253,10 +253,10 @@ public async Task ProjectThatDoesNotSupportEnC_Language(bool breakMode)
solution = solution.WithDocumentText(document1.Id, CreateText("dummy2"));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
var document2 = solution.GetDocument(document1.Id);
diagnostics = await service.GetDocumentDiagnosticsAsync(document2, s_noActiveSpans, CancellationToken.None);
@@ -296,7 +296,7 @@ public void F() {}
}
"""));
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
@@ -335,10 +335,10 @@ class C { int Y => 2; }
var diagnostics1 = await service.GetDocumentDiagnosticsAsync(generatedDocument, s_noActiveSpans, CancellationToken.None);
Assert.Empty(diagnostics1);
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
EndDebuggingSession(debuggingSession);
}
@@ -415,7 +415,7 @@ End Class
var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None);
AssertEx.Empty(diagnostics);
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
@@ -500,7 +500,7 @@ End Class
var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None);
AssertEx.Empty(diagnostics);
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(isWarning ? ModuleUpdateStatus.None : ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
@@ -576,7 +576,7 @@ End Class
var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None);
AssertEx.Empty(diagnostics);
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
@@ -629,7 +629,7 @@ class A
return null;
};
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
Assert.Empty(results.Diagnostics);
@@ -680,7 +680,7 @@ internal async Task Project_MetadataReferences()
var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None);
AssertEx.Empty(diagnostics);
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
@@ -722,7 +722,7 @@ internal async Task Project_MetadataReferences_RemoveAdd()
// remove dependency:
solution = project.RemoveMetadataReference(libV1).Solution;
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
Assert.Empty(results.Diagnostics);
@@ -730,7 +730,7 @@ internal async Task Project_MetadataReferences_RemoveAdd()
// add newer version:
solution = project.AddMetadataReference(libV2).Solution;
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
@@ -770,7 +770,7 @@ internal async Task Project_MetadataReferences_Add()
// add dependency:
solution = project.AddMetadataReference(libV1).Solution;
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
Assert.Empty(results.Diagnostics);
@@ -805,7 +805,7 @@ internal async Task Project_MetadataReferences_MultipleVersions()
// add version 3:
solution = project.AddMetadataReference(libV3).Solution;
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
@@ -847,8 +847,8 @@ public async Task DesignTimeOnlyDocument()
Assert.Empty(diagnostics);
// validate solution update status and emit - changes made in design-time-only documents are ignored:
- var (updates, _) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
EndDebuggingSession(debuggingSession);
@@ -884,15 +884,15 @@ public async Task DesignTimeOnlyDocument_Dynamic()
solution = solution.WithDocumentText(document1.Id, CreateText("class E {}"));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
- Assert.Empty(emitDiagnostics);
-
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
+
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
}
[Theory, CombinatorialData]
@@ -978,18 +978,18 @@ public async Task DesignTimeOnlyDocument_Wpf([CombinatorialValues(LanguageNames.
Assert.Empty(await service.GetDocumentDiagnosticsAsync(designTimeOnlyDocument2, s_noActiveSpans, CancellationToken.None));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
if (delayLoad)
{
LoadLibraryToDebuggee(moduleId);
// validate solution update status and emit:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(emitDiagnostics);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
}
EndDebuggingSession(debuggingSession);
@@ -1036,19 +1036,21 @@ public async Task ErrorReadingModuleFile(bool breakMode)
var docDiagnostics = await service.GetDocumentDiagnosticsAsync(document2, s_noActiveSpans, CancellationToken.None);
Assert.Empty(docDiagnostics);
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.Equal(
[$"proj: : Error ENC1001: {string.Format(FeaturesResources.ErrorReadingFile, moduleFile.Path, expectedErrorMessage)}"],
InspectDiagnostics(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
+
// correct the error:
EmitLibrary(projectId, source2);
- var (updates2, diagnostics2) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates2.Status);
- Assert.Empty(diagnostics2);
+ var results2 = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results2.ModuleUpdates.Status);
+ Assert.Empty(results2.Diagnostics);
CommitSolutionUpdate(debuggingSession);
@@ -1117,13 +1119,14 @@ public async Task ErrorReadingPdbFile()
Assert.Empty(docDiagnostics);
// an error occurred so we need to call update to determine whether we have changes to apply or not:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.Equal(
[$"proj: {document2.FilePath}: (0,0)-(0,0): Error ENC1006: {string.Format(FeaturesResources.UnableToReadSourceFileOrPdb, sourceFile.Path)}"],
InspectDiagnostics(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
AssertEx.Equal(
@@ -1165,17 +1168,18 @@ public async Task ErrorReadingSourceFile()
Assert.Empty(docDiagnostics);
// an error occurred so we need to call update to determine whether we have changes to apply or not:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.Equal(
[$"test: {document1.FilePath}: (0,0)-(0,0): Error ENC1006: {string.Format(FeaturesResources.UnableToReadSourceFileOrPdb, sourceFile.Path)}"],
InspectDiagnostics(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
fileLock.Dispose();
// try apply changes again:
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.NotEmpty(results.ModuleUpdates.Updates);
Assert.Empty(results.Diagnostics);
@@ -1227,8 +1231,8 @@ public async Task Document_Add(bool breakMode)
var diagnostics2 = await service.GetDocumentDiagnosticsAsync(documentB, s_noActiveSpans, CancellationToken.None);
Assert.Empty(diagnostics2);
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
debuggingSession.DiscardSolutionUpdate();
if (breakMode)
@@ -1279,9 +1283,9 @@ public async Task Document_Delete()
// delete B:
solution = solution.RemoveDocument(documentBId);
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.NotEmpty(updates.Updates);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.NotEmpty(results.ModuleUpdates.Updates);
debuggingSession.DiscardSolutionUpdate();
@@ -1316,9 +1320,9 @@ public async Task Document_RenameAndUpdate()
var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(document2Id), s_noActiveSpans, CancellationToken.None);
AssertEx.Empty(diagnostics);
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.NotEmpty(updates.Updates);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.NotEmpty(results.ModuleUpdates.Updates);
debuggingSession.DiscardSolutionUpdate();
@@ -1381,10 +1385,10 @@ public async Task ModuleDisallowsEditAndContinue_NoChanges(bool breakMode)
// workspace is updated to new version after build completed and the session started:
solution = solution.WithDocumentText(document0.Id, CreateText(source1));
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
if (breakMode)
{
@@ -1419,9 +1423,9 @@ public async Task ModuleDisallowsEditAndContinue_SourceGenerator_NoChanges()
var document1 = solution.Projects.Single().Documents.Single();
solution = solution.WithDocumentText(document1.Id, CreateText(source2));
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
EndDebuggingSession(debuggingSession);
}
@@ -1476,13 +1480,14 @@ void M()
AssertEx.Empty(docDiagnostics);
// validate solution update status and emit:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.Equal(
[$"proj: {document2.FilePath}: (5,0)-(5,32): Error ENC2016: {string.Format(FeaturesResources.EditAndContinueDisallowedByProject, document2.Project.Name, "*message*")}"],
InspectDiagnostics(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
AssertEx.SetEqual([moduleId], debuggingSession.GetTestAccessor().GetModulesPreparedForUpdate());
@@ -1575,11 +1580,13 @@ public async Task RudeEdits(bool breakMode)
InspectDiagnostics(docDiagnostics));
// validate solution update status and emit:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.SequenceEqual(["ENC0110"], InspectDiagnosticIds(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
+
if (breakMode)
{
ExitBreakState(debuggingSession);
@@ -1663,10 +1670,10 @@ public async Task DeferredApplyChangeWithActiveStatementRudeEdits()
ExitBreakState(debuggingSession);
// apply the change:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.NotEmpty(updates.Updates);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.NotEmpty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
CommitSolutionUpdate(debuggingSession);
@@ -1717,15 +1724,17 @@ class C { int Y => 2; }
[$"{generatedDocument.FilePath}: (0,17)-(0,18): Error ENC0110: {string.Format(FeaturesResources.Changing_the_signature_of_0_requires_restarting_the_application_because_it_is_not_supported_by_the_runtime, FeaturesResources.method)}"],
InspectDiagnostics(docDiagnostics));
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.Equal(["ENC0110"], InspectDiagnosticIds(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
}
- [Theory, CombinatorialData]
+ [Theory(Skip = "https://github.com/dotnet/roslyn/issues/79589")]
+ [CombinatorialData]
public async Task RudeEdits_DocumentOutOfSync(bool breakMode)
{
var source0 = "class C1 { void M() { System.Console.WriteLine(0); } }";
@@ -1766,68 +1775,53 @@ public async Task RudeEdits_DocumentOutOfSync(bool breakMode)
Assert.Empty(docDiagnostics);
// the document is out-of-sync, so no rude edits reported:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
+ // project is stale:
+ Assert.True(debuggingSession.LastCommittedSolution.StaleProjects.ContainsKey(projectId));
+
// TODO: warning reported https://github.com/dotnet/roslyn/issues/78125
- // AssertEx.Equal([$"proj.csproj: (0,0)-(0,0): Warning ENC1005: {string.Format(FeaturesResources.DocumentIsOutOfSyncWithDebuggee, sourceFile.Path)}"], InspectDiagnostics(emitDiagnostics));
+ // AssertEx.Equal([$"proj.csproj: (0,0)-(0,0): Warning ENC1005: {string.Format(FeaturesResources.DocumentIsOutOfSyncWithDebuggee, sourceFile.Path)}"], InspectDiagnostics(results.Diagnostics));
// We do not reload the content of out-of-sync file for analyzer query.
// We don't check if the content on disk has been updated to match either.
- // Document state can only be reset via UpdateBaselines.
sourceFile.WriteAllText(source0, Encoding.UTF8);
docDiagnostics = await service.GetDocumentDiagnosticsAsync(document2, s_noActiveSpans, CancellationToken.None);
Assert.Empty(docDiagnostics);
// rebuild triggers reload of out-of-sync file content:
moduleId = EmitAndLoadLibraryToDebuggee(projectId, source0, sourceFilePath: sourceFile.Path);
- debuggingSession.UpdateBaselines(solution.WithDocumentText(documentId, CreateText(source0)), [projectId]);
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
- Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
- Assert.Empty(results.ModuleUpdates.Updates);
- AssertEx.SequenceEqual(["ENC0110"], InspectDiagnosticIds(results.Diagnostics));
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
- // now we see the rude edit:
- docDiagnostics = await service.GetDocumentDiagnosticsAsync(document2, s_noActiveSpans, CancellationToken.None);
- AssertEx.Equal(
- [$"{document2.FilePath}: (0,11)-(0,22): Error ENC0110: {string.Format(FeaturesResources.Changing_the_signature_of_0_requires_restarting_the_application_because_it_is_not_supported_by_the_runtime, FeaturesResources.method)}"],
- InspectDiagnostics(docDiagnostics));
+ // project has been unstaled:
+ Assert.False(debuggingSession.LastCommittedSolution.StaleProjects.ContainsKey(projectId));
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
- Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
- AssertEx.SequenceEqual(["ENC0110"], InspectDiagnosticIds(results.Diagnostics));
+ Assert.Empty(results.Diagnostics);
if (breakMode)
{
ExitBreakState(debuggingSession);
- EndDebuggingSession(debuggingSession);
- }
- else
- {
- EndDebuggingSession(debuggingSession);
}
- AssertEx.SetEqual([moduleId], debuggingSession.GetTestAccessor().GetModulesPreparedForUpdate());
+ EndDebuggingSession(debuggingSession);
if (breakMode)
{
AssertEx.SequenceEqual(
[
- "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=1|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2",
- "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectIdsWithAppliedChanges=|ProjectIdsWithUpdatedBaselines=",
- "Debugging_EncSession_EditSession_RudeEdit: SessionId=1|EditSessionId=2|RudeEditKind=110|RudeEditSyntaxKind=8875|RudeEditBlocking=True|RudeEditProjectId={6A6F7270-0000-4000-8000-000000000000}"
+ "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=1|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2"
], _telemetryLog);
}
else
{
AssertEx.SequenceEqual(
[
- "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=1",
- "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31|ProjectIdsWithAppliedChanges=|ProjectIdsWithUpdatedBaselines=",
- "Debugging_EncSession_EditSession_RudeEdit: SessionId=1|EditSessionId=2|RudeEditKind=110|RudeEditSyntaxKind=8875|RudeEditBlocking=True|RudeEditProjectId={6A6F7270-0000-4000-8000-000000000000}"
+ "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1"
], _telemetryLog);
}
}
@@ -1867,11 +1861,12 @@ public async Task RudeEdits_DocumentWithoutSequencePoints()
InspectDiagnostics(docDiagnostics));
// validate solution update status and emit:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.SequenceEqual(["ENC0023"], InspectDiagnosticIds(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
}
@@ -1909,11 +1904,13 @@ public async Task RudeEdits_DelayLoadedModule()
[$"{document2.FilePath}: (0,24)-(0,25): Error ENC0110: {string.Format(FeaturesResources.Changing_the_signature_of_0_requires_restarting_the_application_because_it_is_not_supported_by_the_runtime, FeaturesResources.method)}"],
InspectDiagnostics(docDiagnostics));
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.SequenceEqual(["ENC0110"], InspectDiagnosticIds(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
+
// load library to the debuggee:
LoadLibraryToDebuggee(moduleId);
@@ -1923,17 +1920,18 @@ public async Task RudeEdits_DelayLoadedModule()
[$"{document2.FilePath}: (0,24)-(0,25): Error ENC0110: {string.Format(FeaturesResources.Changing_the_signature_of_0_requires_restarting_the_application_because_it_is_not_supported_by_the_runtime, FeaturesResources.method)}"],
InspectDiagnostics(docDiagnostics));
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.SequenceEqual(["ENC0110"], InspectDiagnosticIds(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
}
[Theory]
[CombinatorialData]
- public async Task RudeEdits_UpdateBaseline(bool validChangeBeforeRudeEdit, bool allowPartialUpdates)
+ public async Task RudeEdits_UpdateBaseline(bool validChangeBeforeRudeEdit)
{
var source3 = "abstract class C { void F() {} public abstract void G(); }";
var projectDir = Temp.CreateDirectory();
@@ -1956,7 +1954,7 @@ public async Task RudeEdits_UpdateBaseline(bool validChangeBeforeRudeEdit, bool
{
solution = solution.WithDocumentText(documentId, CreateText("abstract class C { void F() {} }"));
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdates);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ProjectsToRebuild);
Assert.Empty(results.ProjectsToRestart);
@@ -1985,29 +1983,21 @@ public async Task RudeEdits_UpdateBaseline(bool validChangeBeforeRudeEdit, bool
InspectDiagnostics(docDiagnostics));
// validate solution update status and emit:
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdates);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
AssertEx.SequenceEqual(["ENC0023"], InspectDiagnosticIds(results.GetAllDiagnostics()));
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
Assert.Empty(results.ModuleUpdates.Updates);
AssertEx.Equal([projectId], results.ProjectsToRebuild);
AssertEx.Equal([projectId], results.ProjectsToRestart.Keys);
- if (allowPartialUpdates)
- {
- // assuming user approved restart and rebuild:
- CommitSolutionUpdate(debuggingSession);
- }
+ // assuming user approved restart and rebuild:
+ CommitSolutionUpdate(debuggingSession);
// rebuild and restart:
_debuggerService.LoadedModules.Remove(moduleId);
File.WriteAllText(sourceFilePath, source3, Encoding.UTF8);
moduleId = EmitAndLoadLibraryToDebuggee(solution.GetRequiredDocument(documentId));
- if (!allowPartialUpdates)
- {
- debuggingSession.UpdateBaselines(solution, results.ProjectsToRebuild);
- }
-
if (validChangeBeforeRudeEdit)
{
// baseline should be removed:
@@ -2027,7 +2017,7 @@ public async Task RudeEdits_UpdateBaseline(bool validChangeBeforeRudeEdit, bool
Assert.Empty(await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None));
// apply valid change:
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdates);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
@@ -2075,10 +2065,10 @@ public async Task SyntaxError()
AssertEx.Empty(diagnostics1);
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Blocked, updates.Status);
- Assert.Empty(updates.Updates);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Blocked, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
EndDebuggingSession(debuggingSession);
@@ -2116,14 +2106,14 @@ public async Task SemanticError()
// The EnC analyzer does not check for and block on all semantic errors as they are already reported by diagnostic analyzer.
// Blocking update on semantic errors would be possible, but the status check is only an optimization to avoid emitting.
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Blocked, updates.Status);
- Assert.Empty(updates.Updates);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ 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([$"{document2.FilePath}: (0,30)-(0,32): Error CS0266: {string.Format(CSharpResources.ERR_NoImplicitConvCast, "long", "int")}"], InspectDiagnostics(emitDiagnostics));
+ AssertEx.Equal([$"proj: {document2.FilePath}: (0,30)-(0,32): Error CS0266: {string.Format(CSharpResources.ERR_NoImplicitConvCast, "long", "int")}"], InspectDiagnostics(results.Diagnostics));
EndDebuggingSession(debuggingSession);
@@ -2186,8 +2176,8 @@ public async Task HasChanges()
Assert.False(await EditSession.HasChangesAsync(oldSolution, solution, sourceFilePath: "NonexistentFile.cs", CancellationToken.None));
// All projects must have no errors.
- var (updates, _) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Blocked, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Blocked, results.ModuleUpdates.Status);
// add a project:
@@ -2552,8 +2542,8 @@ public async Task Project_Add()
.AddTestDocument(sourceB1, path: sourceFileB.Path, out var documentBId).Project.Solution
.AddProjectReference(projectAId, new ProjectReference(projectBId));
- var runningProjects = ImmutableDictionary.Empty
- .Add(projectAId, new RunningProjectInfo() { AllowPartialUpdate = true, RestartWhenChangesHaveNoEffect = false });
+ var runningProjects = ImmutableDictionary.Empty
+ .Add(projectAId, new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = false });
var results = await debuggingSession.EmitSolutionUpdateAsync(solution, runningProjects, s_noActiveSpans, CancellationToken.None);
@@ -2593,8 +2583,8 @@ public async Task ProjectReference_Add()
// Add project reference A -> B
solution = solution.AddProjectReference(projectAId, new ProjectReference(projectBId));
- var runningProjects = ImmutableDictionary.Empty
- .Add(projectAId, new RunningProjectInfo() { AllowPartialUpdate = true, RestartWhenChangesHaveNoEffect = false });
+ var runningProjects = ImmutableDictionary.Empty
+ .Add(projectAId, new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = false });
var results = await debuggingSession.EmitSolutionUpdateAsync(solution, runningProjects, s_noActiveSpans, CancellationToken.None);
@@ -2687,11 +2677,11 @@ public async Task Project_Add_BinaryAlreadyLoaded()
// update document with a valid change:
solution = solution.WithDocumentText(documentB2.Id, CreateText("class B { int F() => 2; }"));
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
// TODO: https://github.com/dotnet/roslyn/issues/1204
// verify valid update
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
ExitBreakState(debuggingSession);
@@ -2832,12 +2822,12 @@ int M()
"""));
// validate solution update status and emit
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check that no types have been updated. this used to throw
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.UpdatedTypes);
debuggingSession.DiscardSolutionUpdate();
@@ -2871,12 +2861,13 @@ public async Task Capabilities_SynthesizedNewType()
AssertEx.Empty(diagnostics);
// They are reported as emit diagnostics
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- AssertEx.Equal([$"{project.FilePath}: (0,0)-(0,0): Error ENC1007: {FeaturesResources.ChangesRequiredSynthesizedType}"], InspectDiagnostics(emitDiagnostics));
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ AssertEx.Equal([$"proj: : Error ENC1007: {FeaturesResources.ChangesRequiredSynthesizedType}"], InspectDiagnostics(results.Diagnostics));
// no emitted delta:
- Assert.Empty(updates.Updates);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
}
@@ -2903,11 +2894,11 @@ public async Task ValidSignificantChange_EmitError()
AssertEx.Empty(diagnostics1);
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- AssertEx.Equal([$"{document2.FilePath}: (0,0)-(0,54): Error CS8055: {string.Format(CSharpResources.ERR_EncodinglessSyntaxTree)}"], InspectDiagnostics(emitDiagnostics));
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ AssertEx.Equal([$"proj: {document2.FilePath}: (0,0)-(0,54): Error CS8055: {string.Format(CSharpResources.ERR_EncodinglessSyntaxTree)}"], InspectDiagnostics(results.Diagnostics));
// no emitted delta:
- Assert.Empty(updates.Updates);
+ Assert.Empty(results.ModuleUpdates.Updates);
// no pending update:
Assert.Null(debuggingSession.GetTestAccessor().GetPendingSolutionUpdate());
@@ -2919,9 +2910,9 @@ public async Task ValidSignificantChange_EmitError()
Assert.Empty(debuggingSession.EditSession.NonRemappableRegions);
// solution update status after discarding an update (still has update ready):
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Blocked, updates.Status);
- AssertEx.Equal([$"{document2.FilePath}: (0,0)-(0,54): Error CS8055: {string.Format(CSharpResources.ERR_EncodinglessSyntaxTree)}"], InspectDiagnostics(emitDiagnostics));
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Blocked, results.ModuleUpdates.Status);
+ AssertEx.Equal([$"proj: {document2.FilePath}: (0,0)-(0,54): Error CS8055: {string.Format(CSharpResources.ERR_EncodinglessSyntaxTree)}"], InspectDiagnostics(results.Diagnostics));
EndDebuggingSession(debuggingSession);
@@ -2996,10 +2987,10 @@ public async Task ValidSignificantChange_ApplyBeforeFileWatcherEvent(bool saveDo
}
// EnC service queries for a document, which triggers read of the source file from disk.
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
ExitBreakState(debuggingSession);
@@ -3010,16 +3001,16 @@ public async Task ValidSignificantChange_ApplyBeforeFileWatcherEvent(bool saveDo
solution = solution.WithDocumentText(documentId, CreateTextFromFile(sourceFile.Path));
var document3 = solution.Projects.Single().Documents.Single();
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
if (saveDocument)
{
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
}
else
{
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
debuggingSession.DiscardSolutionUpdate();
}
@@ -3070,11 +3061,11 @@ public async Task ValidSignificantChange_FileUpdateNotObservedBeforeDebuggingSes
AssertEx.Empty(diagnostics);
// since the document is out-of-sync we need to call update to determine whether we have changes to apply or not:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
// TODO: warning reported https://github.com/dotnet/roslyn/issues/78125
- // AssertEx.Equal([$"test.csproj: (0,0)-(0,0): Warning ENC1005: {string.Format(FeaturesResources.DocumentIsOutOfSyncWithDebuggee, sourceFile.Path)}"], InspectDiagnostics(emitDiagnostics));
+ // AssertEx.Equal([$"test.csproj: (0,0)-(0,0): Warning ENC1005: {string.Format(FeaturesResources.DocumentIsOutOfSyncWithDebuggee, sourceFile.Path)}"], InspectDiagnostics(results.Diagnostics));
// undo:
solution = solution.WithDocumentText(documentId, CreateText(source1));
@@ -3088,14 +3079,14 @@ public async Task ValidSignificantChange_FileUpdateNotObservedBeforeDebuggingSes
Assert.Equal(CommittedSolution.DocumentState.OutOfSync, state);
sourceFile.WriteAllText(source1, Encoding.UTF8);
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
AssertEx.Equal(
[
- $"{project.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, sourceFile.Path)}"
- ], InspectDiagnostics(emitDiagnostics));
+ $"test: {document3.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, sourceFile.Path)}"
+ ], InspectDiagnostics(results.Diagnostics));
// the content actually hasn't changed:
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
EndDebuggingSession(debuggingSession);
}
@@ -3158,10 +3149,10 @@ public async Task ValidSignificantChange_AddedFileNotObservedBeforeDebuggingSess
// AssertEx.Equal(new[] { $"({activeLineSpan1}, LeafFrame)" }, spans.Single().Select(s => s.ToString()));
// No changes.
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
- AssertEx.Empty(emitDiagnostics);
+ AssertEx.Empty(results.Diagnostics);
EndDebuggingSession(debuggingSession);
}
@@ -3197,10 +3188,10 @@ public async Task ValidSignificantChange_DocumentOutOfSync(bool delayLoad)
EnterBreakState(debuggingSession);
// no changes have been made to the project
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(updates.Updates);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ Assert.Empty(results.Diagnostics);
// a file watcher observed a change and updated the document, so it now reflects the content on disk (the code that we compiled):
solution = solution.WithDocumentText(document1.Id, CreateText(sourceOnDisk));
@@ -3210,9 +3201,9 @@ public async Task ValidSignificantChange_DocumentOutOfSync(bool delayLoad)
Assert.Empty(diagnostics);
// the content of the file is now exactly the same as the compiled document, so there is no change to be applied:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(emitDiagnostics);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
EndDebuggingSession(debuggingSession);
@@ -3243,10 +3234,10 @@ public async Task ValidSignificantChange_EmitSuccessful(bool breakMode, bool com
AssertEx.Empty(diagnostics1);
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- ValidateDelta(updates.Updates.Single());
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ ValidateDelta(results.ModuleUpdates.Updates.Single());
void ValidateDelta(ManagedHotReloadUpdate delta)
{
@@ -3265,7 +3256,7 @@ void ValidateDelta(ManagedHotReloadUpdate delta)
// the update should be stored on the service:
var pendingUpdate = debuggingSession.GetTestAccessor().GetPendingSolutionUpdate();
var newBaseline = pendingUpdate.ProjectBaselines.Single();
- AssertEx.Equal(updates.Updates, pendingUpdate.Deltas);
+ AssertEx.Equal(results.ModuleUpdates.Updates, pendingUpdate.Deltas);
Assert.Equal(document2.Project.Id, newBaseline.ProjectId);
Assert.Equal(moduleId, newBaseline.EmitBaseline.OriginalMetadata.GetModuleVersionId());
@@ -3293,9 +3284,9 @@ void ValidateDelta(ManagedHotReloadUpdate delta)
Assert.Same(newBaseline.EmitBaseline, debuggingSession.GetTestAccessor().GetProjectBaselines(document2.Project.Id).Single().EmitBaseline);
// solution update status after committing an update:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
}
else
{
@@ -3305,11 +3296,11 @@ void ValidateDelta(ManagedHotReloadUpdate delta)
Assert.Null(debuggingSession.GetTestAccessor().GetPendingSolutionUpdate());
// solution update status after committing an update:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
- ValidateDelta(updates.Updates.Single());
+ ValidateDelta(results.ModuleUpdates.Updates.Single());
debuggingSession.DiscardSolutionUpdate();
}
@@ -3381,12 +3372,12 @@ public async Task ValidSignificantChange_EmitSuccessful_UpdateDeferred(bool comm
var document2 = solution.GetDocument(document1.Id);
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
// delta to apply:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -3432,9 +3423,9 @@ public async Task ValidSignificantChange_EmitSuccessful_UpdateDeferred(bool comm
var document3 = solution.GetDocument(document1.Id);
solution = solution.WithDocumentText(document3.Id, CreateText("class C1 { void M1() { int a = 3; System.Console.WriteLine(a); } void M2() { System.Console.WriteLine(2); } }"));
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
debuggingSession.DiscardSolutionUpdate();
}
else
@@ -3500,12 +3491,12 @@ partial class C { int Y = 2; }
"""));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -3517,10 +3508,9 @@ partial class C { int Y = 2; }
EndDebuggingSession(debuggingSession);
}
- [Theory]
- [CombinatorialData]
+ [Fact]
[WorkItem("https://github.com/dotnet/roslyn/issues/78244")]
- public async Task MultiProjectUpdates_ValidSignificantChange_RudeEdit(bool allowPartialUpdate)
+ public async Task MultiProjectUpdates_ValidSignificantChange_RudeEdit()
{
using var _ = CreateWorkspace(out var solution, out var service);
@@ -3580,31 +3570,21 @@ void F() {}
InspectDiagnostics(docDiagnostics));
// validate solution update status and emit:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
AssertEx.SequenceEqual(["ENC0023"], InspectDiagnosticIds(results.Diagnostics));
- if (allowPartialUpdate)
- {
- AssertEx.SetEqual([documentBId.ProjectId], results.ProjectsToRebuild);
- AssertEx.SetEqual([documentBId.ProjectId], results.ProjectsToRestart.Keys);
-
- var delta = results.ModuleUpdates.Updates.Single();
- Assert.NotEmpty(delta.ILDelta);
- Assert.NotEmpty(delta.MetadataDelta);
- Assert.NotEmpty(delta.PdbDelta);
- Assert.Equal(1, delta.UpdatedMethods.Length);
+ AssertEx.SetEqual([documentBId.ProjectId], results.ProjectsToRebuild);
+ AssertEx.SetEqual([documentBId.ProjectId], results.ProjectsToRestart.Keys);
- debuggingSession.DiscardSolutionUpdate();
- }
- else
- {
- AssertEx.SetEqual([documentAId.ProjectId, documentBId.ProjectId], results.ProjectsToRebuild);
- AssertEx.SetEqual([documentAId.ProjectId, documentBId.ProjectId], results.ProjectsToRestart.Keys);
+ var delta = results.ModuleUpdates.Updates.Single();
+ Assert.NotEmpty(delta.ILDelta);
+ Assert.NotEmpty(delta.MetadataDelta);
+ Assert.NotEmpty(delta.PdbDelta);
+ Assert.Equal(1, delta.UpdatedMethods.Length);
- Assert.Empty(results.ModuleUpdates.Updates);
- }
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
}
@@ -3672,21 +3652,19 @@ static B()
// TODO: Set RestartWhenChangesHaveNoEffect=true and AllowPartialUpdate=true
// https://github.com/dotnet/roslyn/issues/78244
- var runningProjects = ImmutableDictionary.Empty
- .Add(projectAId, new RunningProjectInfo() { RestartWhenChangesHaveNoEffect = false, AllowPartialUpdate = false })
- .Add(projectBId, new RunningProjectInfo() { RestartWhenChangesHaveNoEffect = false, AllowPartialUpdate = false });
+ var runningProjects = ImmutableDictionary.Empty
+ .Add(projectAId, new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = false })
+ .Add(projectBId, new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = false });
// emit updates:
- var result = await debuggingSession.EmitSolutionUpdateAsync(solution, runningProjects, s_noActiveSpans, CancellationToken.None);
-
- AssertEx.SetEqual([], result.ProjectsToRestart.Select(p => p.Key.DebugName));
+ var results = await debuggingSession.EmitSolutionUpdateAsync(solution, runningProjects, s_noActiveSpans, CancellationToken.None);
- var updates = result.ModuleUpdates;
- AssertEx.SequenceEqual(["ENC0118"], InspectDiagnosticIds(result.GetAllDiagnostics()));
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ AssertEx.SetEqual([], results.ProjectsToRestart.Select(p => p.Key.DebugName));
+ AssertEx.SequenceEqual(["ENC0118"], InspectDiagnosticIds(results.GetAllDiagnostics()));
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- Assert.Equal(2, updates.Updates.Length);
+ Assert.Equal(2, results.ModuleUpdates.Updates.Length);
// Process will be restarted, so discard all updates:
debuggingSession.DiscardSolutionUpdate();
@@ -3737,12 +3715,12 @@ class C { int Y => 2; }
"""));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -3792,7 +3770,7 @@ class C { int Y => 2; }
"""));
// validate solution update status and emit:
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
var generatedFilePath = Path.Combine(
TempRoot.Root,
@@ -3804,6 +3782,7 @@ class C { int Y => 2; }
[$"proj: {generatedFilePath}: (0,0)-(0,56): Error ENC0021: {string.Format(FeaturesResources.Adding_0_requires_restarting_the_application, FeaturesResources.attribute)}"],
InspectDiagnostics(results.Diagnostics));
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
}
@@ -3852,12 +3831,12 @@ int M()
"""));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
var lineUpdate = delta.SequencePoints.Single();
@@ -3902,12 +3881,12 @@ partial class C { int X = 1; }
"""));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -3954,12 +3933,12 @@ class C { int Y => 1; }
"""));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -4000,12 +3979,12 @@ class C { int Y => 1; }
solution = solution.WithAnalyzerConfigDocumentText(configDocument1.Id, GetAnalyzerConfigText(configV2));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -4041,12 +4020,12 @@ public async Task ValidSignificantChange_SourceGenerators_DocumentRemove()
solution = document1.Project.Solution.RemoveDocument(document1.Id);
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -4079,9 +4058,9 @@ public async Task ValidInsignificantChange()
AssertEx.Empty(diagnostics1);
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
// solution has been updated:
var text = await debuggingSession.LastCommittedSolution.GetRequiredProject(document1.Project.Id).GetRequiredDocument(document1.Id).GetTextAsync();
@@ -4123,12 +4102,13 @@ public async Task RudeEdit()
AssertEx.Empty(diagnostics);
// They are reported as emit diagnostics
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- AssertEx.Equal([$"{project.FilePath}: (0,0)-(0,0): Error ENC1007: {FeaturesResources.ChangesRequiredSynthesizedType}"], InspectDiagnostics(emitDiagnostics));
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ AssertEx.Equal([$"proj: : Error ENC1007: {FeaturesResources.ChangesRequiredSynthesizedType}"], InspectDiagnostics(results.Diagnostics));
// no emitted delta:
- Assert.Empty(updates.Updates);
+ Assert.Empty(results.ModuleUpdates.Updates);
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
}
@@ -4186,13 +4166,13 @@ public async Task TwoUpdatesWithLoadedAndUnloadedModule()
solution = solution.WithDocumentText(projectB.Documents.Single().Id, CreateText(source2));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
- var deltaA = updates.Updates.Single(d => d.Module == moduleIdA);
- var deltaB = updates.Updates.Single(d => d.Module == moduleIdB);
- Assert.Equal(2, updates.Updates.Length);
+ var deltaA = results.ModuleUpdates.Updates.Single(d => d.Module == moduleIdA);
+ var deltaB = results.ModuleUpdates.Updates.Single(d => d.Module == moduleIdB);
+ Assert.Equal(2, results.ModuleUpdates.Updates.Length);
// the update should be stored on the service:
var pendingUpdate = debuggingSession.GetTestAccessor().GetPendingSolutionUpdate();
@@ -4219,9 +4199,9 @@ public async Task TwoUpdatesWithLoadedAndUnloadedModule()
Assert.Same(newBaselineA1, debuggingSession.GetTestAccessor().GetProjectBaselines(projectA.Id).Single().EmitBaseline);
Assert.Same(newBaselineB1, debuggingSession.GetTestAccessor().GetProjectBaselines(projectB.Id).Single().EmitBaseline);
- // solution update status after committing an update:(updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ // solution update status after committing an update:results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
ExitBreakState(debuggingSession);
EnterBreakState(debuggingSession);
@@ -4234,13 +4214,13 @@ public async Task TwoUpdatesWithLoadedAndUnloadedModule()
solution = solution.WithDocumentText(projectB.Documents.Single().Id, CreateText(source3));
// validate solution update status and emit:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
- deltaA = updates.Updates.Single(d => d.Module == moduleIdA);
- deltaB = updates.Updates.Single(d => d.Module == moduleIdB);
- Assert.Equal(2, updates.Updates.Length);
+ deltaA = results.ModuleUpdates.Updates.Single(d => d.Module == moduleIdA);
+ deltaB = results.ModuleUpdates.Updates.Single(d => d.Module == moduleIdB);
+ Assert.Equal(2, results.ModuleUpdates.Updates.Length);
// the update should be stored on the service:
pendingUpdate = debuggingSession.GetTestAccessor().GetPendingSolutionUpdate();
@@ -4273,9 +4253,9 @@ public async Task TwoUpdatesWithLoadedAndUnloadedModule()
Assert.Same(newBaselineB2, debuggingSession.GetTestAccessor().GetProjectBaselines(projectB.Id).Single().EmitBaseline);
// solution update status after committing an update:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
ExitBreakState(debuggingSession);
EndDebuggingSession(debuggingSession);
@@ -4330,10 +4310,10 @@ public async Task MultiTargetedPartiallyBuiltProjects()
solution = solution.WithDocumentText(documentA.Id, text2).WithDocumentText(documentB.Id, text2);
// delta emitted only for up-to-date project
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
- AssertEx.SequenceEqual([mvidA], updates.Updates.Select(u => u.Module));
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
+ AssertEx.SequenceEqual([mvidA], results.ModuleUpdates.Updates.Select(u => u.Module));
CommitSolutionUpdate(debuggingSession);
@@ -4346,10 +4326,10 @@ public async Task MultiTargetedPartiallyBuiltProjects()
solution = solution.WithDocumentText(documentA.Id, text0).WithDocumentText(documentB.Id, text0);
// both projects are up-to-date now, but B hasn't changed w.r.t. baseline:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
- AssertEx.SetEqual([mvidA], updates.Updates.Select(u => u.Module));
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
+ AssertEx.SetEqual([mvidA], results.ModuleUpdates.Updates.Select(u => u.Module));
CommitSolutionUpdate(debuggingSession);
@@ -4357,10 +4337,10 @@ public async Task MultiTargetedPartiallyBuiltProjects()
solution = solution.WithDocumentText(documentA.Id, text2).WithDocumentText(documentB.Id, text2);
// project B is considered stale until rebuilt (even though the document content matches now):
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
- AssertEx.SetEqual([mvidA], updates.Updates.Select(u => u.Module));
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
+ AssertEx.SetEqual([mvidA], results.ModuleUpdates.Updates.Select(u => u.Module));
CommitSolutionUpdate(debuggingSession);
@@ -4371,19 +4351,19 @@ public async Task MultiTargetedPartiallyBuiltProjects()
// no changes have been made:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
- Assert.Empty(emitDiagnostics);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
// update source file in the editor:
var text3 = CreateText(source3);
solution = solution.WithDocumentText(documentA.Id, text3).WithDocumentText(documentB.Id, text3);
// both modules updated now:
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
- Assert.Empty(emitDiagnostics);
- AssertEx.SetEqual([mvidA, mvidB2], updates.Updates.Select(u => u.Module));
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ Assert.Empty(results.Diagnostics);
+ AssertEx.SetEqual([mvidA, mvidB2], results.ModuleUpdates.Updates.Select(u => u.Module));
CommitSolutionUpdate(debuggingSession);
EndDebuggingSession(debuggingSession);
@@ -4430,13 +4410,13 @@ public async Task MultiTargeted_AllTargetsStale()
solution = solution.WithDocumentText(documentA.Id, text2).WithDocumentText(documentB.Id, text2);
// no updates
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Equal(ModuleUpdateStatus.None, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status);
AssertEx.Equal(
[
- $"{documentA.Project.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, sourcePath)}",
- $"{documentB.Project.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, sourcePath)}"
- ], InspectDiagnostics(emitDiagnostics));
+ $"A: {documentA.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, sourcePath)}",
+ $"B: {documentB.FilePath}: (0,0)-(0,0): Warning ENC1008: {string.Format(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit, sourcePath)}"
+ ], InspectDiagnostics(results.Diagnostics));
EndDebuggingSession(debuggingSession);
}
@@ -4461,7 +4441,7 @@ public async Task ValidSignificantChange_BaselineCreationFailed_NoStream()
// change the source (valid edit):
solution = solution.WithDocumentText(document1.Id, CreateText("class C1 { void M() { System.Console.WriteLine(2); } }"));
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
AssertEx.Equal(
[$"proj: : Error ENC1001: {string.Format(FeaturesResources.ErrorReadingFile, "test-pdb", new FileNotFoundException().Message)}"],
InspectDiagnostics(results.Diagnostics));
@@ -4497,12 +4477,13 @@ public async Task ValidSignificantChange_BaselineCreationFailed_AssemblyReadErro
var document1 = solution.Projects.Single().Documents.Single();
solution = solution.WithDocumentText(document1.Id, CreateText("class C1 { void M() { System.Console.WriteLine(2); } }"));
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
AssertEx.Equal(
[$"proj: : Error ENC1001: {string.Format(FeaturesResources.ErrorReadingFile, "test-assembly", "*message*")}"],
InspectDiagnostics(results.Diagnostics));
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ debuggingSession.DiscardSolutionUpdate();
EndDebuggingSession(debuggingSession);
@@ -4961,12 +4942,12 @@ void F()
solution = solution.WithDocumentText(document1.Id, CreateText(source2));
// validate solution update status and emit:
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
// check emitted delta:
- var delta = updates.Updates.Single();
+ var delta = results.ModuleUpdates.Updates.Single();
Assert.Empty(delta.ActiveStatements);
Assert.NotEmpty(delta.ILDelta);
Assert.NotEmpty(delta.MetadataDelta);
@@ -5051,10 +5032,12 @@ int F()
[$"{document.FilePath}: (9,8)-(9,13): Error ENC0063: {string.Format(FeaturesResources.Updating_a_0_around_an_active_statement_requires_restarting_the_application, CSharpFeaturesResources.catch_clause)}"],
InspectDiagnostics(docDiagnostics));
- var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
AssertEx.SequenceEqual(["ENC0063"], InspectDiagnosticIds(results.Diagnostics));
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
+ debuggingSession.DiscardSolutionUpdate();
+
// undo the change
solution = solution.WithDocumentText(document.Id, CreateText(source1));
document = solution.GetDocument(document.Id);
@@ -5068,7 +5051,7 @@ int F()
Assert.Empty(docDiagnostics);
// validate solution update status and emit (Hot Reload change):
- results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: false);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
Assert.Empty(results.Diagnostics);
Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
@@ -5134,11 +5117,11 @@ static void F()
solution = solution.WithDocumentText(documentId, CreateText(SourceMarkers.Clear(markedSourceV2)));
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(0x06000003, updates.Updates.Single().UpdatedMethods.Single());
- Assert.Equal(0x02000002, updates.Updates.Single().UpdatedTypes.Single());
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(0x06000003, results.ModuleUpdates.Updates.Single().UpdatedMethods.Single());
+ Assert.Equal(0x02000002, results.ModuleUpdates.Updates.Single().UpdatedTypes.Single());
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
@@ -5154,11 +5137,11 @@ static void F()
solution = solution.WithDocumentText(documentId, CreateText(SourceMarkers.Clear(markedSourceV3)));
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(0x06000003, updates.Updates.Single().UpdatedMethods.Single());
- Assert.Equal(0x02000002, updates.Updates.Single().UpdatedTypes.Single());
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(0x06000003, results.ModuleUpdates.Updates.Single().UpdatedMethods.Single());
+ Assert.Equal(0x02000002, results.ModuleUpdates.Updates.Single().UpdatedTypes.Single());
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
@@ -5190,11 +5173,11 @@ static void F()
solution = solution.WithDocumentText(documentId, CreateText(SourceMarkers.Clear(markedSourceV4)));
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(0x06000003, updates.Updates.Single().UpdatedMethods.Single());
- Assert.Equal(0x02000002, updates.Updates.Single().UpdatedTypes.Single());
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(0x06000003, results.ModuleUpdates.Updates.Single().UpdatedMethods.Single());
+ Assert.Equal(0x02000002, results.ModuleUpdates.Updates.Single().UpdatedTypes.Single());
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
@@ -5309,11 +5292,11 @@ static void F()
var diagnostics = await service.GetDocumentDiagnosticsAsync(document1, s_noActiveSpans, CancellationToken.None);
Assert.Empty(diagnostics);
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(0x06000003, updates.Updates.Single().UpdatedMethods.Single());
- Assert.Equal(0x02000002, updates.Updates.Single().UpdatedTypes.Single());
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(0x06000003, results.ModuleUpdates.Updates.Single().UpdatedMethods.Single());
+ Assert.Equal(0x02000002, results.ModuleUpdates.Updates.Single().UpdatedTypes.Single());
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
@@ -5371,11 +5354,11 @@ static void F()
}
""")));
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(0x06000003, updates.Updates.Single().UpdatedMethods.Single());
- Assert.Equal(0x02000002, updates.Updates.Single().UpdatedTypes.Single());
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(0x06000003, results.ModuleUpdates.Updates.Single().UpdatedMethods.Single());
+ Assert.Equal(0x02000002, results.ModuleUpdates.Updates.Single().UpdatedTypes.Single());
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
@@ -5478,10 +5461,10 @@ static void H()
Assert.Equal(1, oldProject.DocumentIds.Count);
Assert.Equal(2, newProject.DocumentIds.Count);
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, modifiedSolution);
- Assert.Empty(emitDiagnostics);
- Assert.False(updates.Updates.IsEmpty);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, modifiedSolution);
+ Assert.Empty(results.Diagnostics);
+ Assert.False(results.ModuleUpdates.Updates.IsEmpty);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
CommitSolutionUpdate(debuggingSession);
EndDebuggingSession(debuggingSession);
@@ -5524,14 +5507,14 @@ public async Task MultiSession()
var solution1 = solution.WithDocumentText(documentIdA, CreateText("class C { void M() { System.Console.WriteLine(" + i + "); } }"));
- var result1 = await encService.EmitSolutionUpdateAsync(sessionId, solution1, runningProjects: ImmutableDictionary.Empty, s_noActiveSpans, CancellationToken.None);
+ var result1 = await encService.EmitSolutionUpdateAsync(sessionId, solution1, runningProjects: ImmutableDictionary.Empty, s_noActiveSpans, CancellationToken.None);
Assert.Empty(result1.Diagnostics);
Assert.Equal(1, result1.ModuleUpdates.Updates.Length);
encService.DiscardSolutionUpdate(sessionId);
var solution2 = solution1.WithDocumentText(documentIdA, CreateText(source3));
- var result2 = await encService.EmitSolutionUpdateAsync(sessionId, solution2, runningProjects: ImmutableDictionary.Empty, s_noActiveSpans, CancellationToken.None);
+ var result2 = await encService.EmitSolutionUpdateAsync(sessionId, solution2, runningProjects: ImmutableDictionary.Empty, s_noActiveSpans, CancellationToken.None);
Assert.Equal("CS0103", result2.Diagnostics.Single().Diagnostics.Single().Id);
Assert.Empty(result2.ModuleUpdates.Updates);
@@ -5554,7 +5537,7 @@ public async Task Disposal()
EndDebuggingSession(debuggingSession);
// The folling methods shall not be called after the debugging session ended.
- await Assert.ThrowsAsync(async () => await debuggingSession.EmitSolutionUpdateAsync(solution, runningProjects: ImmutableDictionary.Empty, s_noActiveSpans, CancellationToken.None));
+ await Assert.ThrowsAsync(async () => await debuggingSession.EmitSolutionUpdateAsync(solution, runningProjects: ImmutableDictionary.Empty, s_noActiveSpans, CancellationToken.None));
Assert.Throws(() => debuggingSession.BreakStateOrCapabilitiesChanged(inBreakState: true));
Assert.Throws(() => debuggingSession.DiscardSolutionUpdate());
Assert.Throws(() => debuggingSession.CommitSolutionUpdate());
@@ -5605,11 +5588,11 @@ public class C
// lib source is updated:
solution = solution.WithDocumentText(documentId, CreateText(libSource2));
- var (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
- var update = updates.Updates.Single();
+ var update = results.ModuleUpdates.Updates.Single();
GetModuleIds(update.MetadataDelta, out var updateModuleId, out var baseId, out var genId, out var gen);
Assert.Equal(libMvid1, updateModuleId);
Assert.Equal(1, gen);
@@ -5629,13 +5612,13 @@ public class C
}
"""));
- (updates, emitDiagnostics) = await EmitSolutionUpdateAsync(debuggingSession, solution);
- Assert.Empty(emitDiagnostics);
- Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
+ results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ Assert.Empty(results.Diagnostics);
+ Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status);
- Assert.Equal(2, updates.Updates.Length);
- var libUpdate1 = updates.Updates.Single(u => u.Module == libMvid1);
- var libUpdate2 = updates.Updates.Single(u => u.Module == libMvid2);
+ Assert.Equal(2, results.ModuleUpdates.Updates.Length);
+ var libUpdate1 = results.ModuleUpdates.Updates.Single(u => u.Module == libMvid1);
+ var libUpdate2 = results.ModuleUpdates.Updates.Single(u => u.Module == libMvid2);
// update of the original library should chain to its previous delta:
GetModuleIds(libUpdate1.MetadataDelta, out var updateModuleId1, out var baseId1, out var genId1, out var gen1);
diff --git a/src/Features/Test/EditAndContinue/EmitSolutionUpdateResultsTests.cs b/src/Features/Test/EditAndContinue/EmitSolutionUpdateResultsTests.cs
index 0e93680c4a32b..0b3120a89fa18 100644
--- a/src/Features/Test/EditAndContinue/EmitSolutionUpdateResultsTests.cs
+++ b/src/Features/Test/EditAndContinue/EmitSolutionUpdateResultsTests.cs
@@ -53,8 +53,8 @@ private static ImmutableArray CreateProjectRudeEdits(IEnumer
.OrderBy(g => g.Key)
.Select(g => new ProjectDiagnostics(g.Key, [.. g.Select(e => Diagnostic.Create(EditAndContinueDiagnosticDescriptors.GetDescriptor(e.kind), Location.None))]))];
- private static ImmutableDictionary CreateRunningProjects(IEnumerable<(ProjectId id, bool noEffectRestarts)> projectIds, bool allowPartialUpdate = true)
- => projectIds.ToImmutableDictionary(keySelector: e => e.id, elementSelector: e => new RunningProjectInfo() { RestartWhenChangesHaveNoEffect = e.noEffectRestarts, AllowPartialUpdate = allowPartialUpdate });
+ private static ImmutableDictionary CreateRunningProjects(IEnumerable<(ProjectId id, bool noEffectRestarts)> projectIds)
+ => projectIds.ToImmutableDictionary(keySelector: e => e.id, elementSelector: e => new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = e.noEffectRestarts });
private static IEnumerable Inspect(ImmutableDictionary> projectsToRestart)
=> projectsToRestart
@@ -382,9 +382,8 @@ public void RunningProjects_NoEffectEditAndRudeEdit_SameProject()
AssertEx.SetEqual([a, b], projectsToRebuild);
}
- [Theory]
- [CombinatorialData]
- public void RunningProjects_NoEffectEditAndRudeEdit_DifferentProjects(bool allowPartialUpdate)
+ [Fact]
+ public void RunningProjects_NoEffectEditAndRudeEdit_DifferentProjects()
{
using var _ = CreateWorkspace(out var solution);
@@ -402,7 +401,7 @@ public void RunningProjects_NoEffectEditAndRudeEdit_DifferentProjects(bool allow
CreateValidUpdates(p0, q),
CreateProjectRudeEdits(blocking: [p1, p2], noEffect: [q]),
addedUnbuiltProjects: [],
- CreateRunningProjects([(r0, noEffectRestarts: false), (r1, noEffectRestarts: false), (r2, noEffectRestarts: false)], allowPartialUpdate),
+ CreateRunningProjects([(r0, noEffectRestarts: false), (r1, noEffectRestarts: false), (r2, noEffectRestarts: false)]),
out var projectsToRestart,
out var projectsToRebuild);
@@ -413,24 +412,12 @@ public void RunningProjects_NoEffectEditAndRudeEdit_DifferentProjects(bool allow
// ==> R0 has to restart due to rude edits in P1 and P2
// Q has update
// ==> R0 has to restart due to rude edits in P1 and P2
- if (allowPartialUpdate)
- {
- AssertEx.Equal(
- [
- "R0: [P1,P2]",
- "R1: [P1]",
- "R2: [P2]",
- ], Inspect(projectsToRestart));
- }
- else
- {
- AssertEx.Equal(
- [
- "R0: []",
- "R1: [P1]",
- "R2: [P2]",
- ], Inspect(projectsToRestart));
- }
+ AssertEx.Equal(
+ [
+ "R0: [P1,P2]",
+ "R1: [P1]",
+ "R2: [P2]",
+ ], Inspect(projectsToRestart));
AssertEx.SetEqual([r0, r1, r2], projectsToRebuild);
}
@@ -482,7 +469,7 @@ public void RunningProjects_RudeEditAndUpdate_DependentOnRebuiltProject()
CreateValidUpdates(c),
CreateProjectRudeEdits(blocking: [b], noEffect: []),
addedUnbuiltProjects: [],
- CreateRunningProjects([(a, noEffectRestarts: false)], allowPartialUpdate: true),
+ CreateRunningProjects([(a, noEffectRestarts: false)]),
out var projectsToRestart,
out var projectsToRebuild);
@@ -513,7 +500,7 @@ public void RunningProjects_AddedProject_NotImpactingRunningProject()
CreateValidUpdates(c),
CreateProjectRudeEdits(blocking: [], noEffect: []),
addedUnbuiltProjects: [b],
- CreateRunningProjects([(a, noEffectRestarts: false)], allowPartialUpdate: true),
+ CreateRunningProjects([(a, noEffectRestarts: false)]),
out var projectsToRestart,
out var projectsToRebuild);
@@ -540,7 +527,7 @@ public void RunningProjects_AddedProject_ImpactingRunningProject()
CreateValidUpdates(c),
CreateProjectRudeEdits(blocking: [], noEffect: []),
addedUnbuiltProjects: [b],
- CreateRunningProjects([(a, noEffectRestarts: false), (e, noEffectRestarts: false)], allowPartialUpdate: true),
+ CreateRunningProjects([(a, noEffectRestarts: false), (e, noEffectRestarts: false)]),
out var projectsToRestart,
out var projectsToRebuild);
@@ -556,9 +543,8 @@ public void RunningProjects_AddedProject_ImpactingRunningProject()
AssertEx.SetEqual([a, b, e], projectsToRebuild);
}
- [Theory]
- [CombinatorialData]
- public void RunningProjects_RudeEditAndUpdate_Independent(bool allowPartialUpdate)
+ [Fact]
+ public void RunningProjects_RudeEditAndUpdate_Independent()
{
using var _ = CreateWorkspace(out var solution);
@@ -573,31 +559,17 @@ public void RunningProjects_RudeEditAndUpdate_Independent(bool allowPartialUpdat
CreateValidUpdates(c),
CreateProjectRudeEdits(blocking: [d], noEffect: []),
addedUnbuiltProjects: [],
- CreateRunningProjects([(a, noEffectRestarts: false), (b, noEffectRestarts: false)], allowPartialUpdate),
+ CreateRunningProjects([(a, noEffectRestarts: false), (b, noEffectRestarts: false)]),
out var projectsToRestart,
out var projectsToRebuild);
- if (allowPartialUpdate)
- {
- // D has rude edit => B has to restart
- AssertEx.Equal(["B: [D]"], Inspect(projectsToRestart));
- AssertEx.SetEqual([b], projectsToRebuild);
- }
- else
- {
- AssertEx.Equal(
- [
- "A: []",
- "B: [D]",
- ], Inspect(projectsToRestart));
-
- AssertEx.SetEqual([a, b], projectsToRebuild);
- }
+ // D has rude edit => B has to restart
+ AssertEx.Equal(["B: [D]"], Inspect(projectsToRestart));
+ AssertEx.SetEqual([b], projectsToRebuild);
}
- [Theory]
- [CombinatorialData]
- public void RunningProjects_NoEffectEditAndUpdate(bool allowPartialUpdate)
+ [Fact]
+ public void RunningProjects_NoEffectEditAndUpdate()
{
using var _ = CreateWorkspace(out var solution);
@@ -612,7 +584,7 @@ public void RunningProjects_NoEffectEditAndUpdate(bool allowPartialUpdate)
CreateValidUpdates(c, d),
CreateProjectRudeEdits(blocking: [], noEffect: [d]),
addedUnbuiltProjects: [],
- CreateRunningProjects([(a, noEffectRestarts: false), (b, noEffectRestarts: true)], allowPartialUpdate),
+ CreateRunningProjects([(a, noEffectRestarts: false), (b, noEffectRestarts: true)]),
out var projectsToRestart,
out var projectsToRebuild);
@@ -620,22 +592,11 @@ public void RunningProjects_NoEffectEditAndUpdate(bool allowPartialUpdate)
// ==> B has to restart
// C has update, A -> C, B -> C, B restarting
// ==> A has to restart even though it does not restart on no-effect edits
- if (allowPartialUpdate)
- {
- AssertEx.Equal(
- [
- "A: [D]",
- "B: [D]",
- ], Inspect(projectsToRestart));
- }
- else
- {
- AssertEx.Equal(
- [
- "A: []",
- "B: [D]",
- ], Inspect(projectsToRestart));
- }
+ AssertEx.Equal(
+ [
+ "A: [D]",
+ "B: [D]",
+ ], Inspect(projectsToRestart));
AssertEx.SetEqual([a, b], projectsToRebuild);
}
diff --git a/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs b/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs
index 40e1521986f9d..0001339a8a846 100644
--- a/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs
+++ b/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs
@@ -176,9 +176,9 @@ await localWorkspace.ChangeSolutionAsync(localWorkspace.CurrentSolution
var diagnosticDescriptor1 = EditAndContinueDiagnosticDescriptors.GetDescriptor(EditAndContinueErrorCode.ErrorReadingFile);
- var runningProjects1 = new Dictionary
+ var runningProjects1 = new Dictionary
{
- { project.Id, new RunningProjectInfo() { RestartWhenChangesHaveNoEffect = true, AllowPartialUpdate = true} }
+ { project.Id, new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = true } }
}.ToImmutableDictionary();
mockEncService.EmitSolutionUpdateImpl = (solution, runningProjects, activeStatementSpanProvider) =>
diff --git a/src/Features/Test/EditAndContinue/WatchHotReloadServiceTests.cs b/src/Features/Test/EditAndContinue/WatchHotReloadServiceTests.cs
index 028161f3b8df0..8b1c1e1c1c1ab 100644
--- a/src/Features/Test/EditAndContinue/WatchHotReloadServiceTests.cs
+++ b/src/Features/Test/EditAndContinue/WatchHotReloadServiceTests.cs
@@ -37,15 +37,9 @@ private static Task GetCommittedDocumentTextAsync(WatchHotReloadServ
.GetRequiredDocument(documentId)
.GetTextAsync();
- [Theory]
- [CombinatorialData]
- public async Task Test(bool requireCommit)
+ [Fact]
+ public async Task Test()
{
- // See https://github.com/dotnet/sdk/blob/main/src/BuiltInTools/dotnet-watch/HotReload/CompilationHandler.cs#L125
-
- // Note that xUnit does not run test case of a theory in parallel, so we can set global state here:
- WatchHotReloadService.RequireCommit = requireCommit;
-
var source1 = "class C { void M() { System.Console.WriteLine(1); } }";
var source2 = "class C { void M() { System.Console.WriteLine(2); /*2*/} }";
var source3 = "class C { void M() { System.Console.WriteLine(2); /*3*/} }";
@@ -89,10 +83,7 @@ public async Task Test(bool requireCommit)
Assert.Equal(1, result.ProjectUpdates.Length);
AssertEx.Equal([0x02000002], result.ProjectUpdates[0].UpdatedTypes);
- if (requireCommit)
- {
- hotReload.CommitUpdate();
- }
+ hotReload.CommitUpdate();
var updatedText = await GetCommittedDocumentTextAsync(hotReload, documentIdA);
Assert.Equal(source2, updatedText.ToString());
@@ -124,12 +115,9 @@ public async Task Test(bool requireCommit)
AssertEx.SetEqual(["P"], result.ProjectsToRestart.Select(p => solution.GetRequiredProject(p.Key).Name));
AssertEx.SetEqual(["P"], result.ProjectsToRebuild.Select(p => solution.GetRequiredProject(p).Name));
- if (requireCommit)
- {
- // Emulate the user making choice to not restart.
- // dotnet-watch then waits until Ctrl+R forces restart.
- hotReload.DiscardUpdate();
- }
+ // Emulate the user making choice to not restart.
+ // dotnet-watch then waits until Ctrl+R forces restart.
+ hotReload.DiscardUpdate();
updatedText = await GetCommittedDocumentTextAsync(hotReload, documentIdA);
Assert.Equal(source3, updatedText.ToString());
diff --git a/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs b/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs
index 308fc11242d2c..fe27c3d83ce62 100644
--- a/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs
+++ b/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs
@@ -219,28 +219,14 @@ internal static void DiscardSolutionUpdate(DebuggingSession session)
internal static void EndDebuggingSession(DebuggingSession session)
=> session.EndSession(out _);
- internal static async Task<(ModuleUpdates updates, ImmutableArray diagnostics)> EmitSolutionUpdateAsync(
- DebuggingSession session,
- Solution solution,
- ActiveStatementSpanProvider? activeStatementSpanProvider = null)
- {
- var runningProjects = solution.ProjectIds.ToImmutableDictionary(
- keySelector: id => id,
- elementSelector: id => new RunningProjectInfo() { AllowPartialUpdate = false, RestartWhenChangesHaveNoEffect = false });
-
- var result = await session.EmitSolutionUpdateAsync(solution, runningProjects, activeStatementSpanProvider ?? s_noActiveSpans, CancellationToken.None);
- return (result.ModuleUpdates, result.Diagnostics.OrderBy(d => d.ProjectId.DebugName).ToImmutableArray().ToDiagnosticData(solution));
- }
-
internal static async ValueTask EmitSolutionUpdateAsync(
DebuggingSession session,
Solution solution,
- bool allowPartialUpdate,
ActiveStatementSpanProvider? activeStatementSpanProvider = null)
{
var runningProjects = solution.ProjectIds.ToImmutableDictionary(
keySelector: id => id,
- elementSelector: id => new RunningProjectInfo() { AllowPartialUpdate = allowPartialUpdate, RestartWhenChangesHaveNoEffect = false });
+ elementSelector: id => new RunningProjectOptions() { RestartWhenChangesHaveNoEffect = false });
var results = await session.EmitSolutionUpdateAsync(solution, runningProjects, activeStatementSpanProvider ?? s_noActiveSpans, CancellationToken.None);
@@ -249,26 +235,14 @@ internal static async ValueTask EmitSolutionUpdateAsy
Assert.Equal(hasTransientError, results.ProjectsToRestart.Any());
Assert.Equal(hasTransientError, results.ProjectsToRebuild.Any());
- if (!allowPartialUpdate)
- {
- // No updates should be produced if transient error is reported:
- Assert.True(!hasTransientError || results.ModuleUpdates.Updates.IsEmpty);
- }
-
return results;
}
- internal static IEnumerable InspectDiagnostics(ImmutableArray actual)
- => actual.Select(InspectDiagnostic);
-
- internal static string InspectDiagnostic(DiagnosticData diagnostic)
- => $"{(string.IsNullOrWhiteSpace(diagnostic.DataLocation.MappedFileSpan.Path) ? diagnostic.ProjectId.ToString() : diagnostic.DataLocation.MappedFileSpan.ToString())}: {diagnostic.Severity} {diagnostic.Id}: {diagnostic.Message}";
-
internal static IEnumerable InspectDiagnostics(ImmutableArray actual)
- => actual.SelectMany(pd => pd.Diagnostics.Select(d => $"{pd.ProjectId.DebugName}: {InspectDiagnostic(d)}"));
+ => actual.SelectMany(pd => pd.Diagnostics.Select(d => $"{pd.ProjectId.DebugName}: {InspectDiagnostic(d)}")).Order();
internal static IEnumerable InspectDiagnostics(ImmutableArray<(ProjectId project, ImmutableArray diagnostics)> diagnostics)
- => diagnostics.SelectMany(pd => pd.diagnostics.Select(d => $"{pd.project.DebugName}: {InspectDiagnostic(d)}"));
+ => diagnostics.SelectMany(pd => pd.diagnostics.Select(d => $"{pd.project.DebugName}: {InspectDiagnostic(d)}")).Order();
internal static string InspectDiagnostic(Diagnostic actual)
=> $"{Inspect(actual.Location)}: {actual.Severity} {actual.Id}: {actual.GetMessage()}";
diff --git a/src/Features/TestUtilities/EditAndContinue/MockEditAndContinueService.cs b/src/Features/TestUtilities/EditAndContinue/MockEditAndContinueService.cs
index 4a90b5ecf172f..0d384f2ac1eee 100644
--- a/src/Features/TestUtilities/EditAndContinue/MockEditAndContinueService.cs
+++ b/src/Features/TestUtilities/EditAndContinue/MockEditAndContinueService.cs
@@ -23,10 +23,9 @@ internal sealed class MockEditAndContinueService() : IEditAndContinueService
public Func, bool, bool, DebuggingSessionId>? StartDebuggingSessionImpl;
public Action? EndDebuggingSessionImpl;
- public Func, ActiveStatementSpanProvider, EmitSolutionUpdateResults>? EmitSolutionUpdateImpl;
+ public Func, ActiveStatementSpanProvider, EmitSolutionUpdateResults>? EmitSolutionUpdateImpl;
public Action? OnSourceFileUpdatedImpl;
public Action? CommitSolutionUpdateImpl;
- public Action>? UpdateBaselinesImpl;
public Action? BreakStateOrCapabilitiesChangedImpl;
public Action? DiscardSolutionUpdateImpl;
public Func>? GetDocumentDiagnosticsImpl;
@@ -40,10 +39,7 @@ public void CommitSolutionUpdate(DebuggingSessionId sessionId)
public void DiscardSolutionUpdate(DebuggingSessionId sessionId)
=> DiscardSolutionUpdateImpl?.Invoke();
- public void UpdateBaselines(DebuggingSessionId sessionId, Solution solution, ImmutableArray rebuiltProjects)
- => UpdateBaselinesImpl?.Invoke(solution, rebuiltProjects);
-
- public ValueTask EmitSolutionUpdateAsync(DebuggingSessionId sessionId, Solution solution, ImmutableDictionary runningProjects, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken)
+ public ValueTask EmitSolutionUpdateAsync(DebuggingSessionId sessionId, Solution solution, ImmutableDictionary runningProjects, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken)
=> new((EmitSolutionUpdateImpl ?? throw new NotImplementedException()).Invoke(solution, runningProjects, activeStatementSpanProvider));
public void EndDebuggingSession(DebuggingSessionId sessionId)
diff --git a/src/VisualStudio/DevKit/Impl/EditAndContinue/ManagedHotReloadLanguageServiceBridge.cs b/src/VisualStudio/DevKit/Impl/EditAndContinue/ManagedHotReloadLanguageServiceBridge.cs
index 21f848e25a5ab..a015293e27d8f 100644
--- a/src/VisualStudio/DevKit/Impl/EditAndContinue/ManagedHotReloadLanguageServiceBridge.cs
+++ b/src/VisualStudio/DevKit/Impl/EditAndContinue/ManagedHotReloadLanguageServiceBridge.cs
@@ -18,7 +18,7 @@ namespace Microsoft.CodeAnalysis.EditAndContinue;
[ExportBrokeredService(ManagedHotReloadLanguageServiceDescriptor.MonikerName, ManagedHotReloadLanguageServiceDescriptor.ServiceVersion, Audience = ServiceAudience.Local)]
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
-internal sealed partial class ManagedHotReloadLanguageServiceBridge(InternalContracts.IManagedHotReloadLanguageService2 service) : IManagedHotReloadLanguageService2, IExportedBrokeredService
+internal sealed partial class ManagedHotReloadLanguageServiceBridge(InternalContracts.IManagedHotReloadLanguageService3 service) : IManagedHotReloadLanguageService3, IExportedBrokeredService
{
ServiceRpcDescriptor IExportedBrokeredService.Descriptor
=> ManagedHotReloadLanguageServiceDescriptor.Descriptor;
@@ -41,17 +41,23 @@ public ValueTask ExitBreakStateAsync(CancellationToken cancellationToken)
public ValueTask OnCapabilitiesChangedAsync(CancellationToken cancellationToken)
=> service.OnCapabilitiesChangedAsync(cancellationToken);
- public async ValueTask GetUpdatesAsync(CancellationToken cancellationToken)
- => (await service.GetUpdatesAsync(cancellationToken).ConfigureAwait(false)).FromContract();
+ [Obsolete]
+ public ValueTask GetUpdatesAsync(CancellationToken cancellationToken)
+ => throw new NotImplementedException();
- public async ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
- => (await service.GetUpdatesAsync(runningProjects, cancellationToken).ConfigureAwait(false)).FromContract();
+ [Obsolete]
+ public ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
+ => throw new NotImplementedException();
+
+ public async ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
+ => (await service.GetUpdatesAsync(runningProjects.SelectAsArray(static info => info.ToContract()), cancellationToken).ConfigureAwait(false)).FromContract();
public ValueTask CommitUpdatesAsync(CancellationToken cancellationToken)
=> service.CommitUpdatesAsync(cancellationToken);
+ [Obsolete]
public ValueTask UpdateBaselinesAsync(ImmutableArray projectPaths, CancellationToken cancellationToken)
- => service.UpdateBaselinesAsync(projectPaths, cancellationToken);
+ => throw new NotImplementedException();
public ValueTask DiscardUpdatesAsync(CancellationToken cancellationToken)
=> service.DiscardUpdatesAsync(cancellationToken);
diff --git a/src/Workspaces/Remote/Core/EditAndContinue/ManagedHotReloadLanguageService.cs b/src/Workspaces/Remote/Core/EditAndContinue/ManagedHotReloadLanguageService.cs
index 70df9645d436f..6c21fb5f82d94 100644
--- a/src/Workspaces/Remote/Core/EditAndContinue/ManagedHotReloadLanguageService.cs
+++ b/src/Workspaces/Remote/Core/EditAndContinue/ManagedHotReloadLanguageService.cs
@@ -14,7 +14,6 @@
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
-using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
@@ -23,12 +22,13 @@ namespace Microsoft.CodeAnalysis.EditAndContinue;
[Export(typeof(IManagedHotReloadLanguageService))]
[Export(typeof(IManagedHotReloadLanguageService2))]
+[Export(typeof(IManagedHotReloadLanguageService3))]
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed partial class ManagedHotReloadLanguageService(
IServiceBrokerProvider serviceBrokerProvider,
IEditAndContinueService encService,
- SolutionSnapshotRegistry solutionSnapshotRegistry) : IManagedHotReloadLanguageService2
+ SolutionSnapshotRegistry solutionSnapshotRegistry) : IManagedHotReloadLanguageService3
{
private sealed class PdbMatchingSourceTextProvider : IPdbMatchingSourceTextProvider
{
@@ -156,34 +156,9 @@ public ValueTask CommitUpdatesAsync(CancellationToken cancellationToken)
return ValueTask.CompletedTask;
}
- public async ValueTask UpdateBaselinesAsync(ImmutableArray projectPaths, CancellationToken cancellationToken)
- {
- if (_disabled)
- {
- return;
- }
-
- try
- {
- Contract.ThrowIfNull(_debuggingSession);
-
- var currentDesignTimeSolution = await GetCurrentDesignTimeSolutionAsync(cancellationToken).ConfigureAwait(false);
- var currentCompileTimeSolution = GetCurrentCompileTimeSolution(currentDesignTimeSolution);
-
- _committedDesignTimeSolution = currentDesignTimeSolution;
-
- var projectIds = from path in projectPaths
- let projectId = currentCompileTimeSolution.Projects.FirstOrDefault(project => project.FilePath == path)?.Id
- where projectId != null
- select projectId;
-
- encService.UpdateBaselines(_debuggingSession.Value, currentCompileTimeSolution, [.. projectIds]);
- }
- catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken))
- {
- Disable();
- }
- }
+ [Obsolete]
+ public ValueTask UpdateBaselinesAsync(ImmutableArray projectPaths, CancellationToken cancellationToken)
+ => throw new NotImplementedException();
public ValueTask DiscardUpdatesAsync(CancellationToken cancellationToken)
{
@@ -269,10 +244,15 @@ public async ValueTask HasChangesAsync(string? sourceFilePath, Cancellatio
}
}
+ [Obsolete]
public ValueTask GetUpdatesAsync(CancellationToken cancellationToken)
- => GetUpdatesAsync(runningProjects: [], cancellationToken);
+ => throw new NotImplementedException();
+
+ [Obsolete]
+ public ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
+ => throw new NotImplementedException();
- public async ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
+ public async ValueTask GetUpdatesAsync(ImmutableArray runningProjects, CancellationToken cancellationToken)
{
if (_disabled)
{
@@ -285,24 +265,17 @@ public async ValueTask GetUpdatesAsync(ImmutableArray.GetInstance(out var runningProjectPaths);
- runningProjectPaths.AddAll(runningProjects);
-
- // TODO: Update once implemented: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2449700
- var runningProjectInfos = solution.Projects.Where(p => p.FilePath != null && runningProjectPaths.Contains(p.FilePath)).ToImmutableDictionary(
- keySelector: static p => p.Id,
- elementSelector: static p => new RunningProjectInfo { RestartWhenChangesHaveNoEffect = false, AllowPartialUpdate = false });
+ var runningProjectOptions = runningProjects.ToRunningProjectOptions(solution, static info => (info.ProjectInstanceId.ProjectFilePath, info.ProjectInstanceId.TargetFramework, info.RestartAutomatically));
EmitSolutionUpdateResults.Data results;
try
{
- results = (await encService.EmitSolutionUpdateAsync(_debuggingSession.Value, solution, runningProjectInfos, s_emptyActiveStatementProvider, cancellationToken).ConfigureAwait(false)).Dehydrate();
+ results = (await encService.EmitSolutionUpdateAsync(_debuggingSession.Value, solution, runningProjectOptions, s_emptyActiveStatementProvider, cancellationToken).ConfigureAwait(false)).Dehydrate();
}
catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken))
{
- results = EmitSolutionUpdateResults.Data.CreateFromInternalError(solution, e.Message, runningProjectInfos);
+ results = EmitSolutionUpdateResults.Data.CreateFromInternalError(solution, e.Message, runningProjectOptions);
}
// Only store the solution if we have any changes to apply, otherwise CommitUpdatesAsync/DiscardUpdatesAsync won't be called.
@@ -314,11 +287,15 @@ public async ValueTask GetUpdatesAsync(ImmutableArray GetProjectPaths(IEnumerable ids)
- => ids.SelectAsArray(id => solution.GetRequiredProject(id).FilePath!);
+ ToProjectIntanceIds(results.ProjectsToRebuild),
+ ToProjectIntanceIds(results.ProjectsToRestart.Keys));
+
+ ImmutableArray ToProjectIntanceIds(IEnumerable ids)
+ => ids.SelectAsArray(id =>
+ {
+ var project = solution.GetRequiredProject(id);
+ return new ProjectInstanceId(project.FilePath!, project.State.NameAndFlavor.flavor ?? "");
+ });
}
catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken))
{
diff --git a/src/Workspaces/Remote/ServiceHub/Services/EditAndContinue/RemoteEditAndContinueService.cs b/src/Workspaces/Remote/ServiceHub/Services/EditAndContinue/RemoteEditAndContinueService.cs
index 7d5be3e678b67..e9594d527b3cf 100644
--- a/src/Workspaces/Remote/ServiceHub/Services/EditAndContinue/RemoteEditAndContinueService.cs
+++ b/src/Workspaces/Remote/ServiceHub/Services/EditAndContinue/RemoteEditAndContinueService.cs
@@ -141,7 +141,7 @@ public ValueTask> GetDocumentDiagnosticsAsync(Che
/// Remote API.
///
public ValueTask EmitSolutionUpdateAsync(
- Checksum solutionChecksum, RemoteServiceCallbackId callbackId, DebuggingSessionId sessionId, ImmutableDictionary runningProjects, CancellationToken cancellationToken)
+ Checksum solutionChecksum, RemoteServiceCallbackId callbackId, DebuggingSessionId sessionId, ImmutableDictionary runningProjects, CancellationToken cancellationToken)
{
return RunServiceAsync(solutionChecksum, async solution =>
{
@@ -182,18 +182,6 @@ public ValueTask DiscardSolutionUpdateAsync(DebuggingSessionId sessionId, Cancel
}, cancellationToken);
}
- ///
- /// Remote API.
- ///
- public ValueTask UpdateBaselinesAsync(Checksum solutionChecksum, DebuggingSessionId sessionId, ImmutableArray rebuiltProjects, CancellationToken cancellationToken)
- {
- return RunServiceAsync(solutionChecksum, solution =>
- {
- GetService().UpdateBaselines(sessionId, solution, rebuiltProjects);
- return default;
- }, cancellationToken);
- }
-
///
/// Remote API.
///