Skip to content

Commit 6c7ade3

Browse files
authored
Update debugger contracts to 18.0.0-beta.25353.1 (#79277)
1 parent 1dbf599 commit 6c7ade3

32 files changed

+616
-798
lines changed

eng/Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
<!--
118118
VS Debugger
119119
-->
120-
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Contracts" Version="17.13.0-beta.25105.1" />
120+
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Contracts" Version="18.0.0-beta.25359.1" />
121121
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Engine-implementation" Version="17.13.1121201-preview" />
122122
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Metadata-implementation" Version="17.13.1121201-preview" />
123123

src/EditorFeatures/Core/EditAndContinue/Contracts/ContractWrappers.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Collections.Generic;
56
using System.Collections.Immutable;
7+
using System.Linq;
68
using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue;
79
using Microsoft.VisualStudio.Debugger.Contracts.HotReload;
810
using InternalContracts = Microsoft.CodeAnalysis.Contracts.EditAndContinue;
@@ -23,6 +25,12 @@ public static InternalContracts.ManagedMethodId ToContract(this ManagedMethodId
2325
public static InternalContracts.SourceSpan ToContract(this SourceSpan id)
2426
=> new(id.StartLine, id.StartColumn, id.EndLine, id.EndColumn);
2527

28+
public static InternalContracts.ProjectInstanceId ToContract(this ProjectInstanceId id)
29+
=> new(id.ProjectFilePath, id.TargetFramework);
30+
31+
public static InternalContracts.RunningProjectInfo ToContract(this RunningProjectInfo id)
32+
=> new(id.ProjectInstanceId.ToContract(), id.RestartAutomatically);
33+
2634
public static InternalContracts.ManagedHotReloadAvailability ToContract(this ManagedHotReloadAvailability value)
2735
=> new((InternalContracts.ManagedHotReloadAvailabilityStatus)value.Status, value.LocalizedMessage);
2836

@@ -41,7 +49,7 @@ public static ManagedHotReloadUpdate FromContract(this InternalContracts.Managed
4149
exceptionRegions: update.ExceptionRegions.SelectAsArray(FromContract));
4250

4351
public static ManagedHotReloadUpdates FromContract(this InternalContracts.ManagedHotReloadUpdates updates)
44-
=> new(updates.Updates.FromContract(), updates.Diagnostics.FromContract(), updates.ProjectsToRebuild, updates.ProjectsToRestart);
52+
=> new(updates.Updates.FromContract(), updates.Diagnostics.FromContract(), updates.ProjectsToRebuild.SelectAsArray(FromContract), updates.ProjectsToRestart.SelectAsArray(FromContract));
4553

4654
public static ImmutableArray<ManagedHotReloadUpdate> FromContract(this ImmutableArray<InternalContracts.ManagedHotReloadUpdate> diagnostics)
4755
=> diagnostics.SelectAsArray(FromContract);
@@ -61,6 +69,9 @@ public static ManagedModuleMethodId FromContract(this InternalContracts.ManagedM
6169
public static SourceSpan FromContract(this InternalContracts.SourceSpan id)
6270
=> new(id.StartLine, id.StartColumn, id.EndLine, id.EndColumn);
6371

72+
public static ProjectInstanceId FromContract(this InternalContracts.ProjectInstanceId id)
73+
=> new(id.ProjectFilePath, id.TargetFramework);
74+
6475
public static ManagedExceptionRegionUpdate FromContract(this InternalContracts.ManagedExceptionRegionUpdate update)
6576
=> new(FromContract(update.Method), update.Delta, FromContract(update.NewSpan));
6677

src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageService.cs

Lines changed: 22 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
namespace Microsoft.CodeAnalysis.EditAndContinue;
2222

2323
[Shared]
24-
[Export(typeof(IManagedHotReloadLanguageService))]
25-
[Export(typeof(IManagedHotReloadLanguageService2))]
24+
[Export(typeof(IManagedHotReloadLanguageService3))]
2625
[Export(typeof(IEditAndContinueSolutionProvider))]
2726
[Export(typeof(EditAndContinueLanguageService))]
2827
[ExportMetadata("UIContext", EditAndContinueUIContext.EncCapableProjectExistsInWorkspaceUIContextString)]
@@ -34,7 +33,7 @@ internal sealed class EditAndContinueLanguageService(
3433
Lazy<IManagedHotReloadService> debuggerService,
3534
PdbMatchingSourceTextProvider sourceTextProvider,
3635
IEditAndContinueLogReporter logReporter,
37-
IDiagnosticsRefresher diagnosticRefresher) : IManagedHotReloadLanguageService2, IEditAndContinueSolutionProvider
36+
IDiagnosticsRefresher diagnosticRefresher) : IManagedHotReloadLanguageService3
3837
{
3938
private sealed class NoSessionException : InvalidOperationException
4039
{
@@ -236,59 +235,9 @@ public async ValueTask DiscardUpdatesAsync(CancellationToken cancellationToken)
236235
}
237236
}
238237

239-
public async ValueTask UpdateBaselinesAsync(ImmutableArray<string> projectPaths, CancellationToken cancellationToken)
240-
{
241-
if (_disabled)
242-
{
243-
return;
244-
}
245-
246-
var currentDesignTimeSolution = GetCurrentDesignTimeSolution();
247-
var currentCompileTimeSolution = GetCurrentCompileTimeSolution(currentDesignTimeSolution);
248-
249-
try
250-
{
251-
SolutionCommitted?.Invoke(currentDesignTimeSolution);
252-
}
253-
catch (Exception e) when (FatalError.ReportAndCatch(e))
254-
{
255-
}
256-
257-
_committedDesignTimeSolution = currentDesignTimeSolution;
258-
var projectIds = GetProjectIds(projectPaths, currentCompileTimeSolution);
259-
260-
try
261-
{
262-
await GetDebuggingSession().UpdateBaselinesAsync(currentCompileTimeSolution, projectIds, cancellationToken).ConfigureAwait(false);
263-
}
264-
catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken))
265-
{
266-
}
267-
268-
foreach (var projectId in projectIds)
269-
{
270-
workspaceProvider.Value.Workspace.EnqueueUpdateSourceGeneratorVersion(projectId, forceRegeneration: false);
271-
}
272-
}
273-
274-
private ImmutableArray<ProjectId> GetProjectIds(ImmutableArray<string> projectPaths, Solution solution)
275-
{
276-
using var _ = ArrayBuilder<ProjectId>.GetInstance(out var projectIds);
277-
foreach (var path in projectPaths)
278-
{
279-
var projectId = solution.Projects.FirstOrDefault(project => project.FilePath == path)?.Id;
280-
if (projectId != null)
281-
{
282-
projectIds.Add(projectId);
283-
}
284-
else
285-
{
286-
logReporter.Report($"Project with path '{path}' not found in the current solution.", LogMessageSeverity.Info);
287-
}
288-
}
289-
290-
return projectIds.ToImmutable();
291-
}
238+
[Obsolete]
239+
public ValueTask UpdateBaselinesAsync(ImmutableArray<string> projectPaths, CancellationToken cancellationToken)
240+
=> throw new NotImplementedException();
292241

293242
public async ValueTask EndSessionAsync(CancellationToken cancellationToken)
294243
{
@@ -359,9 +308,13 @@ public async ValueTask<bool> HasChangesAsync(string? sourceFilePath, Cancellatio
359308

360309
[Obsolete]
361310
public ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(CancellationToken cancellationToken)
362-
=> GetUpdatesAsync(runningProjects: [], cancellationToken);
311+
=> throw new NotImplementedException();
363312

364-
public async ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<string> runningProjects, CancellationToken cancellationToken)
313+
[Obsolete]
314+
public ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<string> runningProjects, CancellationToken cancellationToken)
315+
=> throw new NotImplementedException();
316+
317+
public async ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<RunningProjectInfo> runningProjects, CancellationToken cancellationToken)
365318
{
366319
if (_disabled)
367320
{
@@ -371,22 +324,13 @@ public async ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<s
371324
var designTimeSolution = GetCurrentDesignTimeSolution();
372325
var solution = GetCurrentCompileTimeSolution(designTimeSolution);
373326
var activeStatementSpanProvider = GetActiveStatementSpanProvider(solution);
327+
var runningProjectOptions = runningProjects.ToRunningProjectOptions(solution, static info => (info.ProjectInstanceId.ProjectFilePath, info.ProjectInstanceId.TargetFramework, info.RestartAutomatically));
374328

375-
using var _ = PooledHashSet<string>.GetInstance(out var runningProjectPaths);
376-
runningProjectPaths.AddAll(runningProjects);
377-
378-
// TODO: Update once implemented: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2449700
379-
var runningProjectInfos = solution.Projects.Where(p => p.FilePath != null && runningProjectPaths.Contains(p.FilePath)).ToImmutableDictionary(
380-
keySelector: static p => p.Id,
381-
elementSelector: static p => new RunningProjectInfo { RestartWhenChangesHaveNoEffect = false, AllowPartialUpdate = false });
382-
383-
var result = await GetDebuggingSession().EmitSolutionUpdateAsync(solution, runningProjectInfos, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false);
329+
var result = await GetDebuggingSession().EmitSolutionUpdateAsync(solution, runningProjectOptions, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false);
384330

385331
switch (result.ModuleUpdates.Status)
386332
{
387-
case ModuleUpdateStatus.Ready when result.ProjectsToRebuild.IsEmpty:
388-
// We have updates to be applied and no rude edits.
389-
//
333+
case ModuleUpdateStatus.Ready:
390334
// The debugger will call Commit/Discard on the solution
391335
// based on whether the updates will be applied successfully or not.
392336
_pendingUpdatedDesignTimeSolution = designTimeSolution;
@@ -422,10 +366,14 @@ await solution.GetDocumentAsync(diagnostic.DocumentId, includeSourceGenerated: t
422366
return new ManagedHotReloadUpdates(
423367
result.ModuleUpdates.Updates.FromContract(),
424368
result.GetAllDiagnostics().FromContract(),
425-
GetProjectPaths(result.ProjectsToRebuild),
426-
GetProjectPaths(result.ProjectsToRestart.Keys));
369+
ToProjectIntanceIds(result.ProjectsToRebuild),
370+
ToProjectIntanceIds(result.ProjectsToRestart.Keys));
427371

428-
ImmutableArray<string> GetProjectPaths(IEnumerable<ProjectId> ids)
429-
=> ids.SelectAsArray(id => solution.GetRequiredProject(id).FilePath!);
372+
ImmutableArray<ProjectInstanceId> ToProjectIntanceIds(IEnumerable<ProjectId> ids)
373+
=> ids.SelectAsArray(id =>
374+
{
375+
var project = solution.GetRequiredProject(id);
376+
return new ProjectInstanceId(project.FilePath!, project.State.NameAndFlavor.flavor ?? "");
377+
});
430378
}
431379
}

src/EditorFeatures/Core/EditAndContinue/EditAndContinueLanguageServiceBridge.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.EditAndContinue;
1515
/// TODO (https://github.com/dotnet/roslyn/issues/72713):
1616
/// Once debugger is updated to use the brokered service, this class should be removed and <see cref="EditAndContinueLanguageService"/> should be exported directly.
1717
/// </summary>
18-
internal sealed partial class ManagedEditAndContinueLanguageServiceBridge(EditAndContinueLanguageService service) : IManagedHotReloadLanguageService2
18+
internal sealed partial class ManagedEditAndContinueLanguageServiceBridge(EditAndContinueLanguageService service) : IManagedHotReloadLanguageService3
1919
{
2020
public ValueTask StartSessionAsync(CancellationToken cancellationToken)
2121
=> service.StartSessionAsync(cancellationToken);
@@ -34,16 +34,21 @@ public ValueTask OnCapabilitiesChangedAsync(CancellationToken cancellationToken)
3434

3535
[Obsolete]
3636
public ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(CancellationToken cancellationToken)
37-
=> service.GetUpdatesAsync(cancellationToken);
37+
=> throw new NotImplementedException();
3838

39+
[Obsolete]
3940
public ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<string> runningProjects, CancellationToken cancellationToken)
41+
=> throw new NotImplementedException();
42+
43+
public ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<RunningProjectInfo> runningProjects, CancellationToken cancellationToken)
4044
=> service.GetUpdatesAsync(runningProjects, cancellationToken);
4145

4246
public ValueTask CommitUpdatesAsync(CancellationToken cancellationToken)
4347
=> service.CommitUpdatesAsync(cancellationToken);
4448

49+
[Obsolete]
4550
public ValueTask UpdateBaselinesAsync(ImmutableArray<string> projectPaths, CancellationToken cancellationToken)
46-
=> service.UpdateBaselinesAsync(projectPaths, cancellationToken);
51+
=> throw new NotImplementedException();
4752

4853
public ValueTask DiscardUpdatesAsync(CancellationToken cancellationToken)
4954
=> service.DiscardUpdatesAsync(cancellationToken);

src/EditorFeatures/ExternalAccess/Debugger/GlassTestsHotReloadService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public void EndDebuggingSession()
8484

8585
public async ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(Solution solution, CancellationToken cancellationToken)
8686
{
87-
var results = (await _encService.EmitSolutionUpdateAsync(GetSessionId(), solution, runningProjects: ImmutableDictionary<ProjectId, RunningProjectInfo>.Empty, s_noActiveStatementSpanProvider, cancellationToken).ConfigureAwait(false)).Dehydrate();
88-
return new ManagedHotReloadUpdates(results.ModuleUpdates.Updates.FromContract(), results.GetAllDiagnostics().FromContract(), [], []);
87+
var results = (await _encService.EmitSolutionUpdateAsync(GetSessionId(), solution, runningProjects: ImmutableDictionary<ProjectId, RunningProjectOptions>.Empty, s_noActiveStatementSpanProvider, cancellationToken).ConfigureAwait(false)).Dehydrate();
88+
return new ManagedHotReloadUpdates(results.ModuleUpdates.Updates.FromContract(), results.GetAllDiagnostics().FromContract(), projectInstancesToRebuild: [], projectInstancesToRestart: []);
8989
}
9090
}

src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,13 @@ await localWorkspace.ChangeSolutionAsync(localWorkspace.CurrentSolution
216216
};
217217
};
218218

219-
var updates = await localService.GetUpdatesAsync(runningProjects: [project.FilePath], CancellationToken.None);
219+
var runningProjectInfo = new DebuggerContracts.RunningProjectInfo()
220+
{
221+
ProjectInstanceId = new DebuggerContracts.ProjectInstanceId(project.FilePath, "net9.0"),
222+
RestartAutomatically = false,
223+
};
224+
225+
var updates = await localService.GetUpdatesAsync(runningProjects: [runningProjectInfo], CancellationToken.None);
220226

221227
Assert.Equal(++observedDiagnosticVersion, diagnosticRefresher.GlobalStateVersion);
222228

@@ -281,7 +287,7 @@ await localWorkspace.ChangeSolutionAsync(localWorkspace.CurrentSolution
281287
};
282288
};
283289

284-
updates = await localService.GetUpdatesAsync(runningProjects: [project.FilePath], CancellationToken.None);
290+
updates = await localService.GetUpdatesAsync(runningProjects: [runningProjectInfo], CancellationToken.None);
285291

286292
Assert.Equal(++observedDiagnosticVersion, diagnosticRefresher.GlobalStateVersion);
287293

src/Features/Core/Portable/Contracts/EditAndContinue/IManagedHotReloadLanguageService.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System;
56
using System.Collections.Immutable;
67
using System.Threading;
78
using System.Threading.Tasks;
@@ -15,6 +16,7 @@ internal interface IManagedHotReloadLanguageService
1516
ValueTask EndSessionAsync(CancellationToken cancellationToken);
1617
ValueTask EnterBreakStateAsync(CancellationToken cancellationToken);
1718
ValueTask ExitBreakStateAsync(CancellationToken cancellationToken);
19+
[Obsolete]
1820
ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(CancellationToken cancellationToken);
1921
ValueTask<bool> HasChangesAsync(string? sourceFilePath, CancellationToken cancellationToken);
2022
ValueTask OnCapabilitiesChangedAsync(CancellationToken cancellationToken);
@@ -23,6 +25,14 @@ internal interface IManagedHotReloadLanguageService
2325

2426
internal interface IManagedHotReloadLanguageService2 : IManagedHotReloadLanguageService
2527
{
28+
[Obsolete]
2629
ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<string> runningProjects, CancellationToken cancellationToken);
30+
31+
[Obsolete]
2732
ValueTask UpdateBaselinesAsync(ImmutableArray<string> projectPaths, CancellationToken cancellationToken);
2833
}
34+
35+
internal interface IManagedHotReloadLanguageService3 : IManagedHotReloadLanguageService2
36+
{
37+
ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<RunningProjectInfo> runningProjects, CancellationToken cancellationToken);
38+
}

src/Features/Core/Portable/Contracts/EditAndContinue/ManagedHotReloadUpdates.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace Microsoft.CodeAnalysis.Contracts.EditAndContinue;
99

1010
[DataContract]
11-
internal readonly struct ManagedHotReloadUpdates(ImmutableArray<ManagedHotReloadUpdate> updates, ImmutableArray<ManagedHotReloadDiagnostic> diagnostics, ImmutableArray<string> projectsToRebuild, ImmutableArray<string> projectsToRestart)
11+
internal readonly struct ManagedHotReloadUpdates(ImmutableArray<ManagedHotReloadUpdate> updates, ImmutableArray<ManagedHotReloadDiagnostic> diagnostics, ImmutableArray<ProjectInstanceId> projectsToRebuild, ImmutableArray<ProjectInstanceId> projectsToRestart)
1212
{
1313
[DataMember(Name = "updates")]
1414
public ImmutableArray<ManagedHotReloadUpdate> Updates { get; } = updates;
@@ -17,8 +17,8 @@ internal readonly struct ManagedHotReloadUpdates(ImmutableArray<ManagedHotReload
1717
public ImmutableArray<ManagedHotReloadDiagnostic> Diagnostics { get; } = diagnostics;
1818

1919
[DataMember(Name = "projectsToRebuild")]
20-
public ImmutableArray<string> ProjectsToRebuild { get; } = projectsToRebuild;
20+
public ImmutableArray<ProjectInstanceId> ProjectsToRebuild { get; } = projectsToRebuild;
2121

2222
[DataMember(Name = "projectsToRestart")]
23-
public ImmutableArray<string> ProjectsToRestart { get; } = projectsToRestart;
23+
public ImmutableArray<ProjectInstanceId> ProjectsToRestart { get; } = projectsToRestart;
2424
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Runtime.Serialization;
6+
7+
namespace Microsoft.CodeAnalysis.Contracts.EditAndContinue;
8+
9+
[DataContract]
10+
internal readonly struct ProjectInstanceId(string projectFilePath, string targetFramework)
11+
{
12+
[DataMember(Name = "projectFilePath")]
13+
public string ProjectFilePath { get; } = projectFilePath;
14+
15+
[DataMember(Name = "targetFramework")]
16+
public string TargetFramework { get; } = targetFramework;
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Runtime.Serialization;
6+
7+
namespace Microsoft.CodeAnalysis.Contracts.EditAndContinue;
8+
9+
[DataContract]
10+
internal readonly struct RunningProjectInfo(ProjectInstanceId projectInstanceId, bool restartAutomatically)
11+
{
12+
[DataMember(Name = "projectInstanceId")]
13+
public ProjectInstanceId ProjectInstanceId { get; } = projectInstanceId;
14+
15+
[DataMember(Name = "restartAutomatically")]
16+
public bool RestartAutomatically { get; } = restartAutomatically;
17+
}

0 commit comments

Comments
 (0)