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: Track documents that do not match the debuggee #38905

Merged
merged 6 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from 5 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
38 changes: 38 additions & 0 deletions src/Compilers/Core/Portable/Debugging/SourceHashAlgorithms.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Debugging
{
/// <summary>
/// Hash algorithms supported by the debugger used for source file checksums stored in the PDB.
/// </summary>
internal static class SourceHashAlgorithms
{
private static readonly Guid s_guidSha1 = unchecked(new Guid((int)0xff1816ec, (short)0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60));
private static readonly Guid s_guidSha256 = unchecked(new Guid((int)0x8829d00f, 0x11b8, 0x4213, 0x87, 0x8b, 0x77, 0x0e, 0x85, 0x97, 0xac, 0x16));

public static bool IsSupportedAlgorithm(SourceHashAlgorithm algorithm)
=> algorithm switch
{
SourceHashAlgorithm.Sha1 => true,
SourceHashAlgorithm.Sha256 => true,
_ => false
};

public static Guid GetAlgorithmGuid(SourceHashAlgorithm algorithm)
=> algorithm switch
{
SourceHashAlgorithm.Sha1 => s_guidSha1,
SourceHashAlgorithm.Sha256 => s_guidSha256,
_ => throw ExceptionUtilities.UnexpectedValue(algorithm),
};

public static SourceHashAlgorithm GetSourceHashAlgorithm(Guid guid)
=> (guid == s_guidSha256) ? SourceHashAlgorithm.Sha256 :
(guid == s_guidSha1) ? SourceHashAlgorithm.Sha1 :
SourceHashAlgorithm.None;
}
}
7 changes: 4 additions & 3 deletions src/Compilers/Core/Portable/EmbeddedText.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
Expand All @@ -10,6 +8,9 @@
using System.Reflection.Metadata;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Debugging;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis
{
Expand Down Expand Up @@ -50,7 +51,7 @@ public sealed class EmbeddedText
private EmbeddedText(string filePath, ImmutableArray<byte> checksum, SourceHashAlgorithm checksumAlgorithm, ImmutableArray<byte> blob)
{
Debug.Assert(filePath?.Length > 0);
Debug.Assert(Cci.DebugSourceDocument.IsSupportedAlgorithm(checksumAlgorithm));
Debug.Assert(SourceHashAlgorithms.IsSupportedAlgorithm(checksumAlgorithm));
Debug.Assert(!blob.IsDefault && blob.Length >= sizeof(int));

FilePath = filePath;
Expand Down
40 changes: 0 additions & 40 deletions src/Compilers/Core/Portable/PEWriter/DebugSourceDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,46 +48,6 @@ public DebugSourceDocument(string location, Guid language, ImmutableArray<byte>
_sourceInfo = Task.FromResult(new DebugSourceInfo(checksum, algorithm));
}

internal static bool IsSupportedAlgorithm(SourceHashAlgorithm algorithm)
{
// Dev12 debugger supports MD5, SHA1.
// Dev14 debugger supports MD5, SHA1, SHA256.
// MD5 is obsolete.

switch (algorithm)
{
case SourceHashAlgorithm.Sha1:
case SourceHashAlgorithm.Sha256:
return true;
default:
return false;
}
}

internal static Guid GetAlgorithmGuid(SourceHashAlgorithm algorithm)
{
Debug.Assert(IsSupportedAlgorithm(algorithm));

// Dev12 debugger supports MD5, SHA1.
// Dev14 debugger supports MD5, SHA1, SHA256.
// MD5 is obsolete.

unchecked
{
switch (algorithm)
{
case SourceHashAlgorithm.Sha1:
return new Guid((int)0xff1816ec, (short)0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60);

case SourceHashAlgorithm.Sha256:
return new Guid((int)0x8829d00f, 0x11b8, 0x4213, 0x87, 0x8b, 0x77, 0x0e, 0x85, 0x97, 0xac, 0x16);

default:
throw ExceptionUtilities.UnexpectedValue(algorithm);
}
}
}

public Guid DocumentType
{
get { return s_corSymDocumentTypeText; }
Expand Down
7 changes: 4 additions & 3 deletions src/Compilers/Core/Portable/PEWriter/DebugSourceInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.CodeAnalysis.Debugging;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Immutable;
Expand Down Expand Up @@ -30,15 +31,15 @@ internal struct DebugSourceInfo
public DebugSourceInfo(
ImmutableArray<byte> checksum,
SourceHashAlgorithm checksumAlgorithm,
ImmutableArray<byte> embeddedTextBlob = default(ImmutableArray<byte>))
: this(checksum, DebugSourceDocument.GetAlgorithmGuid(checksumAlgorithm), embeddedTextBlob)
ImmutableArray<byte> embeddedTextBlob = default)
: this(checksum, SourceHashAlgorithms.GetAlgorithmGuid(checksumAlgorithm), embeddedTextBlob)
{
}

public DebugSourceInfo(
ImmutableArray<byte> checksum,
Guid checksumAlgorithmId,
ImmutableArray<byte> embeddedTextBlob = default(ImmutableArray<byte>))
ImmutableArray<byte> embeddedTextBlob = default)
{
ChecksumAlgorithmId = checksumAlgorithmId;
Checksum = checksum;
Expand Down
3 changes: 2 additions & 1 deletion src/Compilers/Core/Portable/Text/SourceText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis.Debugging;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;

Expand Down Expand Up @@ -67,7 +68,7 @@ internal SourceText(ImmutableArray<byte> checksum, SourceHashAlgorithm checksumA

internal static void ValidateChecksumAlgorithm(SourceHashAlgorithm checksumAlgorithm)
{
if (!Cci.DebugSourceDocument.IsSupportedAlgorithm(checksumAlgorithm))
if (!SourceHashAlgorithms.IsSupportedAlgorithm(checksumAlgorithm))
{
throw new ArgumentException(CodeAnalysisResources.UnsupportedHashAlgorithm, nameof(checksumAlgorithm));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,13 @@ public static void Main()
var analyzer = new CSharpEditAndContinueAnalyzer();

using var workspace = TestWorkspace.CreateCSharp(source1);
var oldProject = workspace.CurrentSolution.Projects.First();
var documentId = oldProject.Documents.First().Id;
var oldSolution = workspace.CurrentSolution;
var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));
var oldDocument = oldSolution.GetDocument(documentId);
var oldProject = oldSolution.Projects.First();
tmat marked this conversation as resolved.
Show resolved Hide resolved
var oldDocument = oldProject.Documents.First();
var oldText = await oldDocument.GetTextAsync();
var oldSyntaxRoot = await oldDocument.GetSyntaxRootAsync();
var documentId = oldDocument.Id;
var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));
var newDocument = newSolution.GetDocument(documentId);
var newText = await newDocument.GetTextAsync();
var newSyntaxRoot = await newDocument.GetSyntaxRootAsync();
Expand All @@ -279,7 +279,7 @@ public static void Main()
var oldStatementSyntax = oldSyntaxRoot.FindNode(oldStatementTextSpan);

var baseActiveStatements = ImmutableArray.Create(ActiveStatementsDescription.CreateActiveStatement(ActiveStatementFlags.IsLeafFrame, oldStatementSpan, DocumentId.CreateNewId(ProjectId.CreateNewId())));
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newDocument, trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, newDocument, trackingServiceOpt: null, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.SemanticEdits[0].PreserveLocalVariables);
Expand Down Expand Up @@ -317,13 +317,14 @@ public static void Main()
var analyzer = new CSharpEditAndContinueAnalyzer();

using var workspace = TestWorkspace.CreateCSharp(source1);
var oldProject = workspace.CurrentSolution.Projects.First();
var documentId = oldProject.Documents.First().Id;
var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.First();
var oldDocument = oldProject.Documents.First();
var documentId = oldDocument.Id;
var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.HasChangesAndErrors);
Expand All @@ -346,9 +347,9 @@ public static void Main()

using var workspace = TestWorkspace.CreateCSharp(source);
var oldProject = workspace.CurrentSolution.Projects.First();
var document = oldProject.Documents.First();
var oldDocument = oldProject.Documents.First();
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, document, trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, oldDocument, trackingServiceOpt: null, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -379,13 +380,16 @@ public static void Main()
var analyzer = new CSharpEditAndContinueAnalyzer();

using var workspace = TestWorkspace.CreateCSharp(source1);
var oldProject = workspace.CurrentSolution.Projects.First();
var documentId = oldProject.Documents.First().Id;

var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.Single();
var oldDocument = oldProject.Documents.Single();
var documentId = oldDocument.Id;

var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand All @@ -410,10 +414,14 @@ public static void Main()

using var workspace = TestWorkspace.CreateCSharp(
source, parseOptions: experimental, compilationOptions: null, exportProvider: null);
var oldProject = workspace.CurrentSolution.Projects.First();
var document = oldProject.Documents.First();

var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.Single();
var oldDocument = oldProject.Documents.Single();
var documentId = oldDocument.Id;

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, document, trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, oldDocument, trackingServiceOpt: null, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -454,13 +462,16 @@ public static void Main()

using var workspace = TestWorkspace.CreateCSharp(
source1, parseOptions: experimental, compilationOptions: null, exportProvider: null);
var oldProject = workspace.CurrentSolution.Projects.First();
var documentId = oldProject.Documents.First().Id;

var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.Single();
var oldDocument = oldProject.Documents.Single();
var documentId = oldDocument.Id;

var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.HasChangesAndErrors);
Expand All @@ -485,10 +496,14 @@ public static void Main()
var analyzer = new CSharpEditAndContinueAnalyzer();

using var workspace = TestWorkspace.CreateCSharp(source);
var oldProject = workspace.CurrentSolution.Projects.First();
var document = oldProject.Documents.First();

var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.Single();
var oldDocument = oldProject.Documents.Single();
var documentId = oldDocument.Id;

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, document, trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, oldDocument, trackingServiceOpt: null, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -521,13 +536,16 @@ public static void Main()
var analyzer = new CSharpEditAndContinueAnalyzer();

using var workspace = TestWorkspace.CreateCSharp(source1);
var oldProject = workspace.CurrentSolution.Projects.First();
var documentId = oldProject.Documents.First().Id;

var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.Single();
var oldDocument = oldProject.Documents.Single();
var documentId = oldDocument.Id;

var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);

Assert.True(result.HasChanges);

Expand Down Expand Up @@ -560,13 +578,16 @@ public static void Main(Bar x)
var analyzer = new CSharpEditAndContinueAnalyzer();

using var workspace = TestWorkspace.CreateCSharp(source1);
var oldProject = workspace.CurrentSolution.Projects.First();
var documentId = oldProject.Documents.First().Id;

var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.Single();
var oldDocument = oldProject.Documents.Single();
var documentId = oldDocument.Id;

var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldDocument, baseActiveStatements, newSolution.GetDocument(documentId), trackingServiceOpt: null, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.HasChangesAndErrors);
Expand Down Expand Up @@ -619,7 +640,7 @@ public class D
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
foreach (var changedDocumentId in changedDocuments)
{
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), trackingServiceOpt: null, CancellationToken.None));
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject.GetDocument(changedDocumentId), baseActiveStatements, newProject.GetDocument(changedDocumentId), trackingServiceOpt: null, CancellationToken.None));
}

Assert.True(result.IsSingle());
Expand All @@ -646,7 +667,7 @@ public static void Main()
var analyzer = new CSharpEditAndContinueAnalyzer();

using var workspace = TestWorkspace.CreateCSharp(source1);
// fork the solution to introduce a change

var oldProject = workspace.CurrentSolution.Projects.Single();
var newDocId = DocumentId.CreateNewId(oldProject.Id);
var oldSolution = workspace.CurrentSolution;
Expand All @@ -667,7 +688,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
foreach (var changedDocumentId in changedDocuments)
{
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), trackingServiceOpt: null, CancellationToken.None));
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject.GetDocument(changedDocumentId), baseActiveStatements, newProject.GetDocument(changedDocumentId), trackingServiceOpt: null, CancellationToken.None));
}

Assert.True(result.IsSingle());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,10 @@ internal static class PredefinedCommandHandlerNames
/// Command handler name for Paste in Paste Tracking.
/// </summary>
public const string PasteTrackingPaste = "Paste Tracking Paste Command Handler";

/// <summary>
/// Command handler name for Edit and Continue file save handler.
/// </summary>
public const string EditAndContinueFileSave = "Edit and Continue save file handler";
tmat marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading