Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EnC refactoring: Align wrappers with contracts better #67967

Merged
merged 5 commits into from
Apr 27, 2023
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
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