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 all 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 @@ -292,7 +292,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.True(result.HasChanges);
var syntaxMap = result.SemanticEdits[0].SyntaxMap;
Expand Down Expand Up @@ -338,7 +338,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.HasChangesAndErrors);
Expand All @@ -364,7 +364,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -405,7 +405,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -438,7 +438,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -489,7 +489,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.True(result.HasChanges);
Assert.True(result.HasChangesAndErrors);
Expand Down Expand Up @@ -522,7 +522,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.False(result.HasChanges);
Assert.False(result.HasChangesAndErrors);
Expand Down Expand Up @@ -565,7 +565,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.True(result.HasChanges);

Expand Down Expand Up @@ -608,7 +608,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None);

Assert.True(result.HasChanges);

Expand Down Expand Up @@ -665,7 +665,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None));
}

Assert.True(result.IsSingle());
Expand Down Expand Up @@ -717,7 +717,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, CancellationToken.None));
}

Assert.True(result.IsSingle());
Expand Down Expand Up @@ -751,7 +751,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, EditAndContinueTestHelpers.Net5RuntimeCapabilities, 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 All @@ -762,5 +762,45 @@ public async Task AnalyzeDocumentAsync_InternalError(bool outOfMemory)
AssertEx.Equal(new[] { expectedDiagnostic }, result.RudeEditErrors.Select(d => d.ToDiagnostic(newSyntaxTree))
.Select(d => $"{d.Id}: {d.GetMessage().Split(new[] { Environment.NewLine }, StringSplitOptions.None).First()}"));
}

[Fact]
public async Task AnalyzeDocumentAsync_NotSupportedByRuntime()
{
var source1 = @"
class C
{
public static void Main()
{
System.Console.WriteLine(1);
}
}
";
var source2 = @"
class C
{
public static void Main()
{
System.Console.WriteLine(2);
}
}
";

using var workspace = TestWorkspace.CreateCSharp(source1, composition: s_composition);

var oldSolution = workspace.CurrentSolution;
var oldProject = oldSolution.Projects.Single();
var documentId = oldProject.Documents.Single().Id;
var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));
var newDocument = newSolution.GetDocument(documentId);

var baseActiveStatements = ImmutableArray.Create<ActiveStatement>();
var analyzer = new CSharpEditAndContinueAnalyzer();

var capabilities = EditAndContinueCapabilities.None;

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

Assert.Equal(RudeEditKind.NotSupportedByRuntime, result.RudeEditErrors.Single().Kind);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,23 @@ internal static void VerifyRudeDiagnostics(
this EditScript<SyntaxNode> editScript,
params RudeEditDiagnosticDescription[] expectedDiagnostics)
{
VerifyRudeDiagnostics(editScript, ActiveStatementsDescription.Empty, expectedDiagnostics);
VerifySemanticDiagnostics(
editScript,
ActiveStatementsDescription.Empty,
capabilities: null,
expectedDiagnostics);
}

internal static void VerifyRudeDiagnostics(
this EditScript<SyntaxNode> editScript,
EditAndContinueCapabilities? capabilities = null,
params RudeEditDiagnosticDescription[] expectedDiagnostics)
{
VerifySemanticDiagnostics(
editScript,
ActiveStatementsDescription.Empty,
capabilities,
expectedDiagnostics);
}

internal static void VerifyRudeDiagnostics(
Expand All @@ -43,6 +59,7 @@ internal static void VerifyRudeDiagnostics(
VerifySemanticDiagnostics(
editScript,
description,
capabilities: null,
expectedDiagnostics);
}

Expand All @@ -68,14 +85,24 @@ internal static void VerifySemanticDiagnostics(
new[] { new DocumentAnalysisResultsDescription(diagnostics: expectedDiagnostics) });
}

internal static void VerifySemanticDiagnostics(
this EditScript<SyntaxNode> editScript,
ActiveStatementsDescription activeStatements,
params RudeEditDiagnosticDescription[] expectedDiagnostics)
{
VerifySemanticDiagnostics(editScript, activeStatements, capabilities: null, expectedDiagnostics);
}

internal static void VerifySemanticDiagnostics(
this EditScript<SyntaxNode> editScript,
ActiveStatementsDescription activeStatements,
EditAndContinueCapabilities? capabilities = null,
params RudeEditDiagnosticDescription[] expectedDiagnostics)
{
VerifySemantics(
new[] { editScript },
new[] { new DocumentAnalysisResultsDescription(activeStatements: activeStatements, diagnostics: expectedDiagnostics) });
new[] { new DocumentAnalysisResultsDescription(activeStatements: activeStatements, diagnostics: expectedDiagnostics) },
capabilities: capabilities);
}

internal static void VerifySemanticDiagnostics(
Expand All @@ -92,28 +119,31 @@ internal static void VerifySemanticDiagnostics(
internal static void VerifySemantics(
this EditScript<SyntaxNode> editScript,
ActiveStatementsDescription activeStatements,
SemanticEditDescription[] expectedSemanticEdits)
SemanticEditDescription[] expectedSemanticEdits,
EditAndContinueCapabilities? capabilities = null)
{
VerifySemantics(
new[] { editScript },
new[] { new DocumentAnalysisResultsDescription(activeStatements, semanticEdits: expectedSemanticEdits) });
new[] { new DocumentAnalysisResultsDescription(activeStatements, semanticEdits: expectedSemanticEdits) },
capabilities: capabilities);
}

internal static void VerifySemantics(
this EditScript<SyntaxNode> editScript,
params SemanticEditDescription[] expectedSemanticEdits)
{
VerifySemantics(editScript, ActiveStatementsDescription.Empty, expectedSemanticEdits);
VerifySemantics(editScript, ActiveStatementsDescription.Empty, expectedSemanticEdits, capabilities: null);
}

internal static void VerifySemantics(
EditScript<SyntaxNode>[] editScripts,
DocumentAnalysisResultsDescription[] expected,
TargetFramework[]? targetFrameworks = null)
TargetFramework[]? targetFrameworks = null,
EditAndContinueCapabilities? capabilities = null)
{
foreach (var targetFramework in targetFrameworks ?? new[] { TargetFramework.NetStandard20, TargetFramework.NetCoreApp })
{
new CSharpEditAndContinueTestHelpers().VerifySemantics(editScripts, targetFramework, expected);
new CSharpEditAndContinueTestHelpers().VerifySemantics(editScripts, targetFramework, expected, capabilities);
}
}
}
Expand Down
Loading