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 - Runtime capabilities support #52566

Merged
merged 33 commits into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b7b107c
Create capabilities parser and tests
davidwengier Apr 14, 2021
393b4d7
Nullable
davidwengier Apr 14, 2021
18bfbbe
Add a temporary shim to get strongly typed capabilities that will be …
davidwengier Apr 14, 2021
2a1b777
Plumb through to analyzer
davidwengier Apr 14, 2021
728cf41
Update tests
davidwengier Apr 14, 2021
12c1c0d
Use flags enum and direct parsing
davidwengier Apr 15, 2021
6e87e88
Fix typo
davidwengier Apr 15, 2021
aeb0833
Pass capabilities into the debug session
davidwengier Apr 15, 2021
dae8308
Move predefined sets into test code
davidwengier Apr 15, 2021
f534ad3
Block additions in existing types
davidwengier Apr 16, 2021
d1b0657
Fix default set so tests pass
davidwengier Apr 18, 2021
b3d7bcf
Add a couple more tests
davidwengier Apr 19, 2021
92e9d43
Report rude edit if runtime doesn't support edit and continue baseline
davidwengier Apr 19, 2021
ddb3c3e
Rude edit for adding a new type
davidwengier Apr 19, 2021
fbdf7dd
Merge remote-tracking branch 'upstream/main' into EnCRuntimeCapabilities
davidwengier Apr 19, 2021
5a5ae34
More rude edits for more things that might not be supported
davidwengier Apr 19, 2021
91d73cb
Fix test
davidwengier Apr 19, 2021
efc45e1
Fix test
davidwengier Apr 19, 2021
51a17ad
Expand the handling of lambdas
davidwengier Apr 20, 2021
cd89703
Fix Spanish tests
davidwengier Apr 20, 2021
ba85d7d
Localize
davidwengier Apr 25, 2021
35bcbd3
Remove helper class in favour of direct enum usage
davidwengier Apr 26, 2021
5491751
Move tests
davidwengier Apr 26, 2021
aeb8c07
Just make the field visible, against every fibre of my training
davidwengier Apr 26, 2021
f244048
Update method signature
davidwengier Apr 26, 2021
90cf9a9
Remove RuntimeEdits
davidwengier Apr 26, 2021
10f94b9
Doc
davidwengier Apr 26, 2021
8105a5e
Cache capabilities
davidwengier Apr 26, 2021
3eb2ee4
Use specific rude edit kind for telemetry purposes
davidwengier Apr 26, 2021
ab78154
Update tests
davidwengier Apr 26, 2021
77fed63
Expand runtime capability for adding new defintions
davidwengier Apr 26, 2021
c412d3b
Missed a word
davidwengier Apr 26, 2021
b26dcad
Rename
davidwengier Apr 26, 2021
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 @@ -289,7 +289,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create(ActiveStatementsDescription.CreateActiveStatement(ActiveStatementFlags.IsLeafFrame, oldStatementSpan, DocumentId.CreateNewId(ProjectId.CreateNewId())));
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newDocument, ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newDocument, ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.True(result.HasChanges);
var syntaxMap = result.SemanticEdits[0].SyntaxMap;
Expand Down Expand Up @@ -335,7 +335,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.HasChangesAndErrors);
Expand All @@ -361,7 +361,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -402,7 +402,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -435,7 +435,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -486,7 +486,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.HasChangesAndErrors);
Expand Down Expand Up @@ -519,7 +519,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -562,7 +562,7 @@ public static void Main()
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.True(result.HasChanges);

Expand Down Expand Up @@ -605,7 +605,7 @@ public static void Main(Bar x)
var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

Assert.True(result.HasChanges);

Expand Down Expand Up @@ -662,7 +662,7 @@ public class D

foreach (var changedDocumentId in changedDocuments)
{
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), ImmutableArray<TextSpan>.Empty, CancellationToken.None));
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None));
}

Assert.True(result.IsSingle());
Expand Down Expand Up @@ -714,7 +714,7 @@ class D

foreach (var changedDocumentId in changedDocuments)
{
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), ImmutableArray<TextSpan>.Empty, CancellationToken.None));
result.Add(await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None));
}

Assert.True(result.IsSingle());
Expand Down Expand Up @@ -748,7 +748,7 @@ public async Task AnalyzeDocumentAsync_InternalError(bool outOfMemory)
}
});

var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newDocument, ImmutableArray<TextSpan>.Empty, CancellationToken.None);
var result = await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newDocument, ImmutableArray<TextSpan>.Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None);

var expectedDiagnostic = outOfMemory ?
$"ENC0089: {string.Format(FeaturesResources.Modifying_source_file_will_prevent_the_debug_session_from_continuing_because_the_file_is_too_big, "src.cs")}" :
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// 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 Xunit;

namespace Microsoft.CodeAnalysis.EditAndContinue.UnitTests
{
public class ManagedEditAndContinueCapabilitiesTests
{
[Fact]
public void Parse()
{
var capabilities = "Baseline";

var service = new ManagedEditAndContinueCapabilities(capabilities);

Assert.True(service.HasCapability(ManagedEditAndContinueCapability.Baseline));
Assert.False(service.HasCapability(ManagedEditAndContinueCapability.RuntimeEdits));
}

[Fact]
public void Parse_CaseSensitive()
{
var capabilities = "BaseLine";

var service = new ManagedEditAndContinueCapabilities(capabilities);

Assert.False(service.HasCapability(ManagedEditAndContinueCapability.Baseline));
}

[Fact]
public void Parse_IgnoreInvalid()
{
var capabilities = "Baseline Invalid RuntimeEdits";

var service = new ManagedEditAndContinueCapabilities(capabilities);

Assert.True(service.HasCapability(ManagedEditAndContinueCapability.Baseline));
Assert.True(service.HasCapability(ManagedEditAndContinueCapability.RuntimeEdits));
}

[Fact]
public void Parse_IgnoreInvalidNumeric()
{
var capabilities = "Baseline 90 RuntimeEdits";

var service = new ManagedEditAndContinueCapabilities(capabilities);

Assert.True(service.HasCapability(ManagedEditAndContinueCapability.Baseline));
Assert.True(service.HasCapability(ManagedEditAndContinueCapability.RuntimeEdits));
}

[Fact]
public void Parse_MultipleSpaces()
{
var capabilities = " Baseline RuntimeEdits ";

var service = new ManagedEditAndContinueCapabilities(capabilities);

Assert.True(service.HasCapability(ManagedEditAndContinueCapability.Baseline));
Assert.True(service.HasCapability(ManagedEditAndContinueCapability.RuntimeEdits));
}

[Fact]
public void HasCapability_IgnoreInvalid()
{
var capabilities = "Baseline";

var service = new ManagedEditAndContinueCapabilities(capabilities);

Assert.False(service.HasCapability((ManagedEditAndContinueCapability)999));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ internal void VerifySemantics(EditScript<SyntaxNode>[] editScripts, TargetFramew
Contract.ThrowIfNull(oldModel);
Contract.ThrowIfNull(newModel);

var result = Analyzer.AnalyzeDocumentAsync(oldProject, oldActiveStatements, newDocument, newActiveStatementSpans, CancellationToken.None).Result;
var result = Analyzer.AnalyzeDocumentAsync(oldProject, oldActiveStatements, newDocument, newActiveStatementSpans, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None).Result;
var oldText = oldDocument.GetTextSynchronously(default);
var newText = newDocument.GetTextSynchronously(default);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ End Class

Dim analyzer = New VisualBasicEditAndContinueAnalyzer()
Dim baseActiveStatements = ImmutableArray.Create(ActiveStatementsDescription.CreateActiveStatement(ActiveStatementFlags.IsLeafFrame, oldStatementSpan, DocumentId.CreateNewId(ProjectId.CreateNewId())))
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newDocument, ImmutableArray(Of TextSpan).Empty, CancellationToken.None)
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newDocument, ImmutableArray(Of TextSpan).Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None)

Assert.True(result.HasChanges)
Dim syntaxMap = result.SemanticEdits(0).SyntaxMap
Expand Down Expand Up @@ -500,7 +500,7 @@ End Class
Dim oldDocument = oldProject.Documents.Single()
Dim baseActiveStatements = ImmutableArray.Create(Of ActiveStatement)()
Dim analyzer = New VisualBasicEditAndContinueAnalyzer()
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray(Of TextSpan).Empty, CancellationToken.None)
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray(Of TextSpan).Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None)

Assert.False(result.HasChanges)
Assert.False(result.HasChangesAndErrors)
Expand Down Expand Up @@ -534,7 +534,7 @@ End Class
Dim analyzer = New VisualBasicEditAndContinueAnalyzer()

Dim baseActiveStatements = ImmutableArray.Create(Of ActiveStatement)()
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray(Of TextSpan).Empty, CancellationToken.None)
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray(Of TextSpan).Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None)

Assert.False(result.HasChanges)
Assert.False(result.HasChangesAndErrors)
Expand All @@ -558,7 +558,7 @@ End Class
Dim oldDocument = oldProject.Documents.Single()
Dim baseActiveStatements = ImmutableArray.Create(Of ActiveStatement)()
Dim analyzer = New VisualBasicEditAndContinueAnalyzer()
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray(Of TextSpan).Empty, CancellationToken.None)
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, oldDocument, ImmutableArray(Of TextSpan).Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None)

Assert.False(result.HasChanges)
Assert.False(result.HasChangesAndErrors)
Expand Down Expand Up @@ -594,7 +594,7 @@ End Class
Dim analyzer = New VisualBasicEditAndContinueAnalyzer()

Dim baseActiveStatements = ImmutableArray.Create(Of ActiveStatement)()
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray(Of TextSpan).Empty, CancellationToken.None)
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray(Of TextSpan).Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None)

' no declaration errors (error in method body is only reported when emitting)
Assert.False(result.HasChangesAndErrors)
Expand Down Expand Up @@ -627,7 +627,7 @@ End Class
Dim analyzer = New VisualBasicEditAndContinueAnalyzer()

Dim baseActiveStatements = ImmutableArray.Create(Of ActiveStatement)()
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray(Of TextSpan).Empty, CancellationToken.None)
Dim result = Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newSolution.GetDocument(documentId), ImmutableArray(Of TextSpan).Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None)

Assert.True(result.HasChanges)

Expand Down Expand Up @@ -697,7 +697,7 @@ End Class
Dim baseActiveStatements = ImmutableArray.Create(Of ActiveStatement)()
Dim analyzer = New VisualBasicEditAndContinueAnalyzer()
For Each changedDocumentId In changedDocuments
result.Add(Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), ImmutableArray(Of TextSpan).Empty, CancellationToken.None))
result.Add(Await analyzer.AnalyzeDocumentAsync(oldProject, baseActiveStatements, newProject.GetDocument(changedDocumentId), ImmutableArray(Of TextSpan).Empty, ManagedEditAndContinueCapabilities.Net5CoreCLR, CancellationToken.None))
Next

Assert.True(result.IsSingle())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ public async Task<DocumentAnalysisResults> AnalyzeDocumentAsync(
ImmutableArray<ActiveStatement> oldActiveStatements,
Document newDocument,
ImmutableArray<TextSpan> newActiveStatementSpans,
ManagedEditAndContinueCapabilities capabilities,
CancellationToken cancellationToken)
{
DocumentAnalysisResults.Log.Write("Analyzing document {0}", newDocument.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,15 @@ public bool TryGetOrCreateEmitBaseline(Project project, out ImmutableArray<Diagn
return true;
}

/// <summary>
/// Gets the capabilities of the runtime with respect to applying code changes.
/// </summary>
public async Task<ManagedEditAndContinueCapabilities> GetCapabilitiesAsync(CancellationToken cancellationToken)
{
var runtimeCapabiltiies = await DebuggerService.GetCapabilitiesAsync(cancellationToken).ConfigureAwait(false);
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
return new ManagedEditAndContinueCapabilities(runtimeCapabiltiies);
}

private static unsafe bool TryCreateInitialBaseline(
CompilationOutputs compilationOutputs,
out ImmutableArray<Diagnostic> diagnostics,
Expand Down
Loading