Skip to content

Commit

Permalink
EnC refactoring: Align wrappers with contracts better (#67967)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat authored Apr 27, 2023
1 parent 6d4997f commit 86469c8
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ public static Contracts.SourceSpan ToContract(this SourceSpan id)
public static Contracts.ManagedHotReloadAvailability ToContract(this ManagedHotReloadAvailability value)
=> new((Contracts.ManagedHotReloadAvailabilityStatus)value.Status, value.LocalizedMessage);

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

public static ImmutableArray<ManagedHotReloadUpdate> FromContract(this ImmutableArray<ModuleUpdate> diagnostics)
public static ImmutableArray<ManagedHotReloadUpdate> FromContract(this ImmutableArray<Contracts.ManagedHotReloadUpdate> diagnostics)
=> diagnostics.SelectAsArray(FromContract);

public static SequencePointUpdates FromContract(this Contracts.SequencePointUpdates updates)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2717,7 +2717,7 @@ public async Task ValidSignificantChange_EmitSuccessful(bool breakMode, bool com
Assert.Equal(ModuleUpdateStatus.Ready, updates.Status);
ValidateDelta(updates.Updates.Single());

void ValidateDelta(ModuleUpdate delta)
void ValidateDelta(ManagedHotReloadUpdate delta)
{
// check emitted delta:
Assert.Empty(delta.ActiveStatements);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,18 @@ void VerifyReanalyzeInvocation(ImmutableArray<DocumentId> documentIds)
Assert.Equal("proj", project.Name);
AssertEx.Equal(activeSpans1, activeStatementSpanProvider(documentId, "test.cs", CancellationToken.None).AsTask().Result);

var deltas = ImmutableArray.Create(new ModuleUpdate(
Module: moduleId1,
ILDelta: ImmutableArray.Create<byte>(1, 2),
MetadataDelta: ImmutableArray.Create<byte>(3, 4),
PdbDelta: ImmutableArray.Create<byte>(5, 6),
UpdatedMethods: ImmutableArray.Create(0x06000001),
UpdatedTypes: ImmutableArray.Create(0x02000001),
SequencePoints: ImmutableArray.Create(new SequencePointUpdates("file.cs", ImmutableArray.Create(new SourceLineUpdate(1, 2)))),
ActiveStatements: ImmutableArray.Create(new ManagedActiveStatementUpdate(instructionId1.Method.Method, instructionId1.ILOffset, span1.ToSourceSpan())),
ExceptionRegions: ImmutableArray.Create(exceptionRegionUpdate1),
RequiredCapabilities: EditAndContinueCapabilities.Baseline));
var deltas = ImmutableArray.Create(new ManagedHotReloadUpdate(
module: moduleId1,
moduleName: "mod",
ilDelta: ImmutableArray.Create<byte>(1, 2),
metadataDelta: ImmutableArray.Create<byte>(3, 4),
pdbDelta: ImmutableArray.Create<byte>(5, 6),
updatedMethods: ImmutableArray.Create(0x06000001),
updatedTypes: ImmutableArray.Create(0x02000001),
sequencePoints: ImmutableArray.Create(new SequencePointUpdates("file.cs", ImmutableArray.Create(new SourceLineUpdate(1, 2)))),
activeStatements: ImmutableArray.Create(new ManagedActiveStatementUpdate(instructionId1.Method.Method, instructionId1.ILOffset, span1.ToSourceSpan())),
exceptionRegions: ImmutableArray.Create(exceptionRegionUpdate1),
requiredCapabilities: EditAndContinueCapabilities.Baseline.ToStringArray()));

var syntaxTree = solution.GetRequiredDocument(documentId).GetSyntaxTreeSynchronously(CancellationToken.None)!;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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;
using System;
using System.Collections.Immutable;

namespace Microsoft.CodeAnalysis.EditAndContinue.Contracts;

[DataContract]
internal readonly struct ManagedHotReloadUpdate
{
[DataMember(Name = "module")]
public Guid Module { get; }

[DataMember(Name = "moduleName")]
public string ModuleName { get; }

[DataMember(Name = "ilDelta")]
public ImmutableArray<byte> ILDelta { get; }

[DataMember(Name = "metadataDelta")]
public ImmutableArray<byte> MetadataDelta { get; }

[DataMember(Name = "pdbDelta")]
public ImmutableArray<byte> PdbDelta { get; }

[DataMember(Name = "updatedTypes")]
public ImmutableArray<int> UpdatedTypes { get; }

[DataMember(Name = "requiredCapabilities")]
public ImmutableArray<string> RequiredCapabilities { get; }

[DataMember(Name = "updatedMethods")]
public ImmutableArray<int> UpdatedMethods { get; }

[DataMember(Name = "sequencePoints")]
public ImmutableArray<SequencePointUpdates> SequencePoints { get; }

[DataMember(Name = "activeStatements")]
public ImmutableArray<ManagedActiveStatementUpdate> ActiveStatements { get; }

[DataMember(Name = "exceptionRegions")]
public ImmutableArray<ManagedExceptionRegionUpdate> ExceptionRegions { get; }

public ManagedHotReloadUpdate(
Guid module,
string moduleName,
ImmutableArray<byte> ilDelta,
ImmutableArray<byte> metadataDelta,
ImmutableArray<byte> pdbDelta,
ImmutableArray<int> updatedTypes,
ImmutableArray<string> requiredCapabilities,
ImmutableArray<int> updatedMethods,
ImmutableArray<SequencePointUpdates> sequencePoints,
ImmutableArray<ManagedActiveStatementUpdate> activeStatements,
ImmutableArray<ManagedExceptionRegionUpdate> exceptionRegions)
{
Module = module;
ModuleName = moduleName;
ILDelta = ilDelta;
MetadataDelta = metadataDelta;
PdbDelta = pdbDelta;
SequencePoints = sequencePoints;
UpdatedMethods = updatedMethods;
UpdatedTypes = updatedTypes;
ActiveStatements = activeStatements;
ExceptionRegions = exceptionRegions;
RequiredCapabilities = requiredCapabilities;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Debugging;
using Microsoft.CodeAnalysis.EditAndContinue.Contracts;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.EditAndContinue.Contracts;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.EditAndContinue
Expand Down Expand Up @@ -100,7 +100,7 @@ internal sealed class DebuggingSession : IDisposable
/// Last array of module updates generated during the debugging session.
/// Useful for crash dump diagnostics.
/// </summary>
private ImmutableArray<ModuleUpdate> _lastModuleUpdatesLog;
private ImmutableArray<ManagedHotReloadUpdate> _lastModuleUpdatesLog;

internal DebuggingSession(
DebuggingSessionId id,
Expand Down
15 changes: 8 additions & 7 deletions src/Features/Core/Portable/EditAndContinue/EditSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ public async ValueTask<SolutionUpdate> EmitSolutionUpdateAsync(Solution solution

log.Write("EmitSolutionUpdate {0}.{1}: '{2}'", updateId.SessionId.Ordinal, updateId.Ordinal, solution.FilePath);

using var _1 = ArrayBuilder<ModuleUpdate>.GetInstance(out var deltas);
using var _1 = ArrayBuilder<ManagedHotReloadUpdate>.GetInstance(out var deltas);
using var _2 = ArrayBuilder<(Guid ModuleId, ImmutableArray<(ManagedModuleMethodId Method, NonRemappableRegion Region)>)>.GetInstance(out var nonRemappableRegions);
using var _3 = ArrayBuilder<ProjectBaseline>.GetInstance(out var newProjectBaselines);
using var _4 = ArrayBuilder<ProjectDiagnostics>.GetInstance(out var diagnostics);
Expand Down Expand Up @@ -1034,17 +1034,18 @@ async ValueTask LogDocumentChangesAsync(int? generation, CancellationToken cance
out var moduleNonRemappableRegions,
out var exceptionRegionUpdates);

var delta = new ModuleUpdate(
var delta = new ManagedHotReloadUpdate(
mvid,
newCompilation.AssemblyName ?? newProject.Name, // used for display in debugger diagnostics
ilStream.ToImmutableArray(),
metadataStream.ToImmutableArray(),
pdbStream.ToImmutableArray(),
projectChanges.LineChanges,
updatedMethodTokens,
changedTypeTokens,
projectChanges.RequiredCapabilities.ToStringArray(),
updatedMethodTokens,
projectChanges.LineChanges,
activeStatementsInUpdatedMethods,
exceptionRegionUpdates,
projectChanges.RequiredCapabilities);
exceptionRegionUpdates);

deltas.Add(delta);

Expand Down Expand Up @@ -1105,7 +1106,7 @@ async ValueTask LogDocumentChangesAsync(int? generation, CancellationToken cance
}
}

private async ValueTask LogDeltaFilesAsync(TraceLog.FileLogger log, ModuleUpdate delta, int baselineGeneration, Project oldProject, Project newProject, CancellationToken cancellationToken)
private async ValueTask LogDeltaFilesAsync(TraceLog.FileLogger log, ManagedHotReloadUpdate delta, int baselineGeneration, Project oldProject, Project newProject, CancellationToken cancellationToken)
{
var sessionId = DebuggingSession.Id;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal readonly struct Data

public static readonly EmitSolutionUpdateResults Empty = new()
{
ModuleUpdates = new ModuleUpdates(ModuleUpdateStatus.None, ImmutableArray<ModuleUpdate>.Empty),
ModuleUpdates = new ModuleUpdates(ModuleUpdateStatus.None, ImmutableArray<ManagedHotReloadUpdate>.Empty),
Diagnostics = ImmutableArray<ProjectDiagnostics>.Empty,
RudeEdits = ImmutableArray<(DocumentId, ImmutableArray<RudeEditDiagnostic>)>.Empty,
SyntaxError = null
Expand Down
18 changes: 2 additions & 16 deletions src/Features/Core/Portable/EditAndContinue/ModuleUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,13 @@
// 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;
using System;
using System.Collections.Immutable;
using System.Runtime.Serialization;
using Microsoft.CodeAnalysis.EditAndContinue.Contracts;

namespace Microsoft.CodeAnalysis.EditAndContinue;

[DataContract]
internal readonly record struct ModuleUpdate(
[property: DataMember(Order = 0)] Guid Module,
[property: DataMember(Order = 1)] ImmutableArray<byte> ILDelta,
[property: DataMember(Order = 2)] ImmutableArray<byte> MetadataDelta,
[property: DataMember(Order = 3)] ImmutableArray<byte> PdbDelta,
[property: DataMember(Order = 4)] ImmutableArray<SequencePointUpdates> SequencePoints,
[property: DataMember(Order = 5)] ImmutableArray<int> UpdatedMethods,
[property: DataMember(Order = 6)] ImmutableArray<int> UpdatedTypes,
[property: DataMember(Order = 7)] ImmutableArray<ManagedActiveStatementUpdate> ActiveStatements,
[property: DataMember(Order = 8)] ImmutableArray<ManagedExceptionRegionUpdate> ExceptionRegions,
[property: DataMember(Order = 9)] EditAndContinueCapabilities RequiredCapabilities);

[DataContract]
internal readonly record struct ModuleUpdates(
[property: DataMember(Order = 0)] ModuleUpdateStatus Status,
[property: DataMember(Order = 1)] ImmutableArray<ModuleUpdate> Updates);
[property: DataMember(Order = 1)] ImmutableArray<ManagedHotReloadUpdate> Updates);
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ namespace Microsoft.CodeAnalysis.EditAndContinue
internal abstract class PendingUpdate
{
public readonly ImmutableArray<ProjectBaseline> ProjectBaselines;
public readonly ImmutableArray<ModuleUpdate> Deltas;
public readonly ImmutableArray<ManagedHotReloadUpdate> Deltas;

public PendingUpdate(
ImmutableArray<ProjectBaseline> projectBaselines,
ImmutableArray<ModuleUpdate> deltas)
ImmutableArray<ManagedHotReloadUpdate> deltas)
{
ProjectBaselines = projectBaselines;
Deltas = deltas;
Expand All @@ -31,7 +31,7 @@ internal sealed class PendingSolutionUpdate : PendingUpdate
public PendingSolutionUpdate(
Solution solution,
ImmutableArray<ProjectBaseline> projectBaselines,
ImmutableArray<ModuleUpdate> deltas,
ImmutableArray<ManagedHotReloadUpdate> deltas,
ImmutableArray<(Guid ModuleId, ImmutableArray<(ManagedModuleMethodId Method, NonRemappableRegion Region)>)> nonRemappableRegions)
: base(projectBaselines, deltas)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public async ValueTask EndDebuggingSessionAsync(Solution compileTimeSolution, Ed
}
else
{
moduleUpdates = new ModuleUpdates(ModuleUpdateStatus.RestartRequired, ImmutableArray<ModuleUpdate>.Empty);
moduleUpdates = new ModuleUpdates(ModuleUpdateStatus.RestartRequired, ImmutableArray<ManagedHotReloadUpdate>.Empty);
diagnosticData = ImmutableArray<DiagnosticData>.Empty;
rudeEdits = ImmutableArray<(DocumentId DocumentId, ImmutableArray<RudeEditDiagnostic> Diagnostics)>.Empty;
syntaxError = null;
Expand All @@ -148,7 +148,7 @@ public async ValueTask EndDebuggingSessionAsync(Solution compileTimeSolution, Ed
{
diagnosticData = GetInternalErrorDiagnosticData(solution, e);
rudeEdits = ImmutableArray<(DocumentId DocumentId, ImmutableArray<RudeEditDiagnostic> Diagnostics)>.Empty;
moduleUpdates = new ModuleUpdates(ModuleUpdateStatus.RestartRequired, ImmutableArray<ModuleUpdate>.Empty);
moduleUpdates = new ModuleUpdates(ModuleUpdateStatus.RestartRequired, ImmutableArray<ManagedHotReloadUpdate>.Empty);
syntaxError = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static SolutionUpdate Blocked(
Diagnostic? syntaxError,
bool hasEmitErrors)
=> new(
new(syntaxError != null || hasEmitErrors ? ModuleUpdateStatus.Blocked : ModuleUpdateStatus.RestartRequired, ImmutableArray<ModuleUpdate>.Empty),
new(syntaxError != null || hasEmitErrors ? ModuleUpdateStatus.Blocked : ModuleUpdateStatus.RestartRequired, ImmutableArray<ManagedHotReloadUpdate>.Empty),
ImmutableArray<(Guid, ImmutableArray<(ManagedModuleMethodId, NonRemappableRegion)>)>.Empty,
ImmutableArray<ProjectBaseline>.Empty,
diagnostics,
Expand Down
2 changes: 2 additions & 0 deletions src/Features/Core/Portable/EditAndContinue/TraceLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ private Arg(int value, StrongBox<EnumType> enumKind)

public object? GetDebuggerDisplay()
=> (!Tokens.IsDefault) ? string.Join(",", Tokens.Select(token => token.ToString("X8"))) :
(Object is ImmutableArray<string> array) ? string.Join(",", array) :
(Object is null) ? Int32 :
(Object is StrongBox<EnumType> { Value: var enumType }) ? enumType switch
{
Expand All @@ -94,6 +95,7 @@ private Arg(int value, StrongBox<EnumType> enumKind)
public static implicit operator Arg(ModuleUpdateStatus value) => new((int)value, s_ModuleUpdateStatus);
public static implicit operator Arg(EditAndContinueCapabilities value) => new((int)value, s_EditAndContinueCapabilities);
public static implicit operator Arg(ImmutableArray<int> tokens) => new(tokens);
public static implicit operator Arg(ImmutableArray<string> items) => new(items);
}

[DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public async Task StartSessionAsync(Solution solution, CancellationToken cancell
}

var updates = results.ModuleUpdates.Updates.SelectAsArray(
update => new Update(update.Module, update.ILDelta, update.MetadataDelta, update.PdbDelta, update.UpdatedTypes, update.RequiredCapabilities.ToStringArray()));
update => new Update(update.Module, update.ILDelta, update.MetadataDelta, update.PdbDelta, update.UpdatedTypes, update.RequiredCapabilities));

var diagnostics = await results.GetAllDiagnosticsAsync(solution, cancellationToken).ConfigureAwait(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ internal sealed class EditAndContinueFeedbackDiagnosticFileProvider : IFeedbackD

private volatile int _isLogCollectionInProgress;

private readonly EditAndContinueLanguageService _encService;
private readonly Lazy<EditAndContinueLanguageService>? _encService;

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public EditAndContinueFeedbackDiagnosticFileProvider(EditAndContinueLanguageService encService)
public EditAndContinueFeedbackDiagnosticFileProvider(
[Import(AllowDefault = true)] Lazy<EditAndContinueLanguageService>? encService = null)
{
_encService = encService;

Expand Down Expand Up @@ -104,15 +105,15 @@ private void OnFeedbackSemaphoreCreatedOrChanged()

if (Interlocked.CompareExchange(ref _isLogCollectionInProgress, 1, 0) == 0)
{
_encService.SetFileLoggingDirectory(GetLogDirectory());
_encService?.Value.SetFileLoggingDirectory(GetLogDirectory());
}
}

private void OnFeedbackSemaphoreDeleted()
{
if (Interlocked.Exchange(ref _isLogCollectionInProgress, 0) == 1)
{
_encService.SetFileLoggingDirectory(logDirectory: null);
_encService?.Value.SetFileLoggingDirectory(logDirectory: null);

// Including the zip files in VS Feedback is currently on best effort basis.
// See https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1714439
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public ValueTask<ImmutableArray<DiagnosticData>> GetDocumentDiagnosticsAsync(Che
{
return new EmitSolutionUpdateResults.Data()
{
ModuleUpdates = new ModuleUpdates(ModuleUpdateStatus.Blocked, ImmutableArray<ModuleUpdate>.Empty),
ModuleUpdates = new ModuleUpdates(ModuleUpdateStatus.Blocked, ImmutableArray<ManagedHotReloadUpdate>.Empty),
Diagnostics = GetUnexpectedUpdateError(solution, e),
RudeEdits = ImmutableArray<(DocumentId DocumentId, ImmutableArray<RudeEditDiagnostic> Diagnostics)>.Empty,
SyntaxError = null,
Expand Down

0 comments on commit 86469c8

Please sign in to comment.