Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
<!--
VS Debugger
-->
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Contracts" Version="18.3.0-beta.26277.4" />
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Contracts" Version="18.3.0-beta.26380.1" />
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Engine-implementation" Version="18.0.1082202-preview" />
<PackageVersion Include="Microsoft.VisualStudio.Debugger.Metadata-implementation" Version="18.0.1082202-preview" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,30 @@ public static InternalContracts.ManagedHotReloadAvailability ToContract(this Man
=> new((InternalContracts.ManagedHotReloadAvailabilityStatus)value.Status, value.LocalizedMessage);

public static ManagedHotReloadUpdate FromContract(this InternalContracts.ManagedHotReloadUpdate update)
=> new(
module: update.Module,
moduleName: update.ModuleName,
ilDelta: update.ILDelta,
metadataDelta: update.MetadataDelta,
pdbDelta: update.PdbDelta,
updatedTypes: update.UpdatedTypes,
requiredCapabilities: update.RequiredCapabilities,
updatedMethods: update.UpdatedMethods,
sequencePoints: update.SequencePoints.SelectAsArray(FromContract),
activeStatements: update.ActiveStatements.SelectAsArray(FromContract),
exceptionRegions: update.ExceptionRegions.SelectAsArray(FromContract));
=> new()
{
Module = update.Module,
ModuleName = update.ModuleName,
ILDelta = update.ILDelta,
MetadataDelta = update.MetadataDelta,
PdbDelta = update.PdbDelta,
UpdatedTypes = update.UpdatedTypes,
RequiredCapabilities = update.RequiredCapabilities,
UpdatedMethods = update.UpdatedMethods,
SequencePoints = update.SequencePoints.SelectAsArray(FromContract),
ActiveStatements = update.ActiveStatements.SelectAsArray(FromContract),
ExceptionRegions = update.ExceptionRegions.SelectAsArray(FromContract)
};

public static ManagedHotReloadUpdates FromContract(this InternalContracts.ManagedHotReloadUpdates updates)
=> new(updates.Updates.FromContract(), updates.Diagnostics.FromContract(), updates.ProjectsToRebuild.SelectAsArray(FromContract), updates.ProjectsToRestart.SelectAsArray(FromContract));
=> new()
{
Updates = updates.Updates.FromContract(),
Diagnostics = updates.Diagnostics.FromContract(),
ProjectInstancesToRebuild = updates.ProjectsToRebuild.SelectAsArray(FromContract),
ProjectInstancesToRestart = updates.ProjectsToRestart.SelectAsArray(FromContract),
HasPendingUpdates = updates.HasPendingUpdates,
};

public static ImmutableArray<ManagedHotReloadUpdate> FromContract(this ImmutableArray<InternalContracts.ManagedHotReloadUpdate> diagnostics)
=> diagnostics.SelectAsArray(FromContract);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Debugger.Contracts.HotReload;
using InternalContracts = Microsoft.CodeAnalysis.Contracts.EditAndContinue;

namespace Microsoft.CodeAnalysis.EditAndContinue;

Expand Down Expand Up @@ -61,4 +60,8 @@ public ValueTask DiscardUpdatesAsync(CancellationToken cancellationToken)

public ValueTask<bool> HasChangesAsync(string? sourceFilePath, CancellationToken cancellationToken)
=> impl.HasChangesAsync(sourceFilePath, cancellationToken);

// internal for testing:
internal ManagedHotReloadLanguageServiceImpl Impl
=> impl;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,20 @@ public NoSessionException()
private DebuggingSessionProxy? _debuggingSession;

private Solution? _pendingUpdatedSolution;
private Solution? _committedSolution;

private Solution? CommittedSolution
{
get;
set
{
field = value;

if (value != null)
{
SolutionCommitted?.Invoke(value);
}
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the same thing as Copilot -- there's no longer a try/catch to report exceptions. Did that turn out to be unnecessary?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was actually a good catch (pun intended ;).

I ended up moving the catch here: https://github.com/dotnet/roslyn/pull/84726/changes#diff-1b2bd8e67dfecf6bcecc504f88921d6e1031d5993291c5d063d384ebaafbda19R47 since that's where we actually call external code we don't control.


public event Action<Solution>? SolutionCommitted;

Expand Down Expand Up @@ -84,7 +97,7 @@ public async ValueTask StartSessionAsync(CancellationToken cancellationToken)
sourceTextProvider.Activate();

var currentSolution = await solutionSnapshotProvider.GetCurrentSolutionAsync(cancellationToken).ConfigureAwait(false);
_committedSolution = currentSolution;
CommittedSolution = currentSolution;

sourceTextProvider.SetBaseline(currentSolution);

Expand Down Expand Up @@ -162,15 +175,7 @@ public async ValueTask CommitUpdatesAsync(CancellationToken cancellationToken)
var committedSolution = Interlocked.Exchange(ref _pendingUpdatedSolution, null);
Contract.ThrowIfNull(committedSolution);

try
{
SolutionCommitted?.Invoke(committedSolution);
}
catch (Exception e) when (FatalError.ReportAndCatch(e))
{
}

_committedSolution = committedSolution;
CommittedSolution = committedSolution;

try
{
Expand Down Expand Up @@ -226,7 +231,7 @@ public async ValueTask EndSessionAsync(CancellationToken cancellationToken)

sourceTextProvider.Deactivate();
_debuggingSession = null;
_committedSolution = null;
CommittedSolution = null;
_pendingUpdatedSolution = null;
}

Expand All @@ -252,8 +257,8 @@ public async ValueTask<bool> HasChangesAsync(string? sourceFilePath, Cancellatio
return false;
}

Contract.ThrowIfNull(_committedSolution);
var oldSolution = _committedSolution;
Contract.ThrowIfNull(CommittedSolution);
var oldSolution = CommittedSolution;
var newSolution = await solutionSnapshotProvider.GetCurrentSolutionAsync(cancellationToken).ConfigureAwait(false);

return (sourceFilePath != null)
Expand Down Expand Up @@ -285,7 +290,14 @@ public async ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<R
{
if (_disabled)
{
return new ManagedHotReloadUpdates([], [], [], []);
return new ManagedHotReloadUpdates()
{
Updates = [],
Diagnostics = [],
ProjectsToRebuild = [],
ProjectsToRestart = [],
HasPendingUpdates = false
};
}

var solution = await solutionSnapshotProvider.GetCurrentSolutionAsync(cancellationToken).ConfigureAwait(false);
Expand All @@ -294,18 +306,18 @@ public async ValueTask<ManagedHotReloadUpdates> GetUpdatesAsync(ImmutableArray<R

var result = await GetDebuggingSession().EmitSolutionUpdateAsync(solution, runningProjectOptions, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false);

switch (result.ModuleUpdates.Status)
switch (result.SolutionAction)
{
case ModuleUpdateStatus.Ready:
case SolutionAction.PendingUpdate:
// The debugger will call Commit/Discard on the solution
// based on whether the updates will be applied successfully or not.
_pendingUpdatedSolution = solution;
break;

case ModuleUpdateStatus.None:
case SolutionAction.Committed:
// No significant changes have been made.
// Commit the solution to apply any changes in comments that do not generate updates.
_committedSolution = solution;
CommittedSolution = solution;
break;
}

Expand All @@ -329,11 +341,14 @@ await solution.GetDocumentAsync(diagnostic.DocumentId, includeSourceGenerated: t

UpdateApplyChangesDiagnostics(applyChangesDiagnostics.ToImmutableOrEmptyAndFree());

return new ManagedHotReloadUpdates(
result.ModuleUpdates.Updates,
result.GetAllDiagnostics(),
ToProjectIntanceIds(result.ProjectsToRebuild),
ToProjectIntanceIds(result.ProjectsToRestart.Keys));
return new ManagedHotReloadUpdates()
{
Updates = result.ModuleUpdates.Updates,
Diagnostics = result.GetAllDiagnostics(),
ProjectsToRebuild = ToProjectIntanceIds(result.ProjectsToRebuild),
ProjectsToRestart = ToProjectIntanceIds(result.ProjectsToRestart.Keys),
HasPendingUpdates = result.SolutionAction == SolutionAction.PendingUpdate
};

ImmutableArray<ProjectInstanceId> ToProjectIntanceIds(IEnumerable<ProjectId> ids)
=> ids.SelectAsArray(id =>
Expand All @@ -342,4 +357,13 @@ ImmutableArray<ProjectInstanceId> ToProjectIntanceIds(IEnumerable<ProjectId> ids
return new ProjectInstanceId(project.FilePath!, project.State.NameAndFlavor.flavor ?? "");
});
}

internal TestAccessor GetTestAccessor()
=> new(this);

internal readonly struct TestAccessor(ManagedHotReloadLanguageServiceImpl instance)
{
public Solution? PendingUpdatedSolution => instance._pendingUpdatedSolution;
public Solution? CommittedSolution => instance.CommittedSolution;
}
}
Loading
Loading