diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs
index 6ce641947edec..422c7a34e5536 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs
@@ -62,26 +62,26 @@ static void Main(string[] args)
public void Method_Body_Delete1()
{
var src1 = "class C { int M() { return 1; } }";
- var src2 = "class C { int M(); }";
+ var src2 = "class C { extern int M(); }";
var edits = GetTopEdits(src1, src2);
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.MethodBodyDelete, "int M()", FeaturesResources.method));
+ Diagnostic(RudeEditKind.ModifiersUpdate, "extern int M()", FeaturesResources.method));
}
[Fact]
public void Method_ExpressionBody_Delete1()
{
var src1 = "class C { int M() => 1; }";
- var src2 = "class C { int M(); }";
+ var src2 = "class C { extern int M(); }";
var edits = GetTopEdits(src1, src2);
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.MethodBodyDelete, "int M()", FeaturesResources.method));
+ Diagnostic(RudeEditKind.ModifiersUpdate, "extern int M()", FeaturesResources.method));
}
[Fact]
@@ -232,7 +232,7 @@ static void Swap(T lhs, T rhs) where T : System.IComparable
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.GenericMethodUpdate, "static void Swap(T lhs, T rhs)", FeaturesResources.method));
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "static void Swap(T lhs, T rhs)"));
}
// Async
@@ -711,7 +711,7 @@ public T this[int i]
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.GenericTypeUpdate, "set", CSharpFeaturesResources.indexer_setter));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "set"));
}
[WorkItem(750244, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/750244")]
@@ -765,7 +765,7 @@ public T this[int i]
// Rude edits of active statements (AS:1) are not reported if the top-level edits are rude.
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.GenericTypeUpdate, "set", CSharpFeaturesResources.indexer_setter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "set"),
Diagnostic(RudeEditKind.ActiveStatementUpdate, "stringCollection[1] = \"hello\";"));
}
@@ -816,7 +816,7 @@ public T this[int i]
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.GenericTypeUpdate, "get", CSharpFeaturesResources.indexer_getter));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "get"));
}
[WorkItem(750244, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/750244")]
@@ -868,7 +868,7 @@ public T this[int i]
// Rude edits of active statements (AS:1) are not reported if the top-level edits are rude.
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.GenericTypeUpdate, "get", CSharpFeaturesResources.indexer_getter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "get"),
Diagnostic(RudeEditKind.ActiveStatementUpdate, "Console.WriteLine(stringCollection[1]);"));
}
@@ -919,7 +919,7 @@ public T this[int i]
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.GenericTypeUpdate, "set", CSharpFeaturesResources.indexer_setter));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "set"));
}
[Fact]
@@ -1018,7 +1018,7 @@ public T this[int i]
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.GenericTypeUpdate, "get", CSharpFeaturesResources.indexer_getter));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "get"));
}
[Fact]
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
index eeb0066db42c8..d0dd3d4d2180e 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
@@ -1496,8 +1496,7 @@ class C
var edits = GetTopEdits(src1, src2);
var active = GetActiveStatements(src1, src2);
- edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.MethodBodyAdd, "get", CSharpFeaturesResources.property_getter));
+ edits.VerifyRudeDiagnostics(active);
}
[Fact]
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs
index 739938b3d8fd4..52c058b281df5 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs
@@ -52,30 +52,30 @@ internal static void VerifyRudeDiagnostics(
internal static void VerifyLineEdits(
this EditScript editScript,
- IEnumerable expectedLineEdits,
- IEnumerable expectedNodeUpdates,
- params RudeEditDiagnosticDescription[] expectedDiagnostics)
+ SourceLineUpdate[] lineEdits,
+ SemanticEditDescription[]? semanticEdits = null,
+ RudeEditDiagnosticDescription[]? diagnostics = null)
{
- Assert.NotEmpty(expectedLineEdits);
+ Assert.NotEmpty(lineEdits);
VerifyLineEdits(
editScript,
- new[] { new SequencePointUpdates(editScript.Match.OldRoot.SyntaxTree.FilePath, expectedLineEdits.ToImmutableArray()) },
- expectedNodeUpdates,
- expectedDiagnostics);
+ new[] { new SequencePointUpdates(editScript.Match.OldRoot.SyntaxTree.FilePath, lineEdits.ToImmutableArray()) },
+ semanticEdits,
+ diagnostics);
}
internal static void VerifyLineEdits(
this EditScript editScript,
- IEnumerable expectedLineEdits,
- IEnumerable expectedNodeUpdates,
- params RudeEditDiagnosticDescription[] expectedDiagnostics)
+ SequencePointUpdates[] lineEdits,
+ SemanticEditDescription[]? semanticEdits = null,
+ RudeEditDiagnosticDescription[]? diagnostics = null)
{
new CSharpEditAndContinueTestHelpers().VerifyLineEdits(
editScript,
- expectedLineEdits,
- expectedNodeUpdates,
- expectedDiagnostics);
+ lineEdits,
+ semanticEdits,
+ diagnostics);
}
internal static void VerifySemanticDiagnostics(
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs
index 794c9d3f61a9e..fd25bce6cc13c 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs
@@ -64,18 +64,18 @@ internal static DocumentAnalysisResultsDescription DocumentResults(
ActiveStatementsDescription? activeStatements = null,
SemanticEditDescription[]? semanticEdits = null,
RudeEditDiagnosticDescription[]? diagnostics = null)
- => new(activeStatements, semanticEdits, diagnostics);
+ => new(activeStatements, semanticEdits, lineEdits: null, diagnostics);
- private static SyntaxTree ParseSource(string markedSource)
+ private static SyntaxTree ParseSource(string markedSource, int documentIndex = 0)
=> SyntaxFactory.ParseSyntaxTree(
ActiveStatementsDescription.ClearTags(markedSource),
CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview),
- path: "test.cs");
+ path: documentIndex.ToString());
- internal static EditScript GetTopEdits(string src1, string src2)
+ internal static EditScript GetTopEdits(string src1, string src2, int documentIndex = 0)
{
- var tree1 = ParseSource(src1);
- var tree2 = ParseSource(src2);
+ var tree1 = ParseSource(src1, documentIndex);
+ var tree2 = ParseSource(src2, documentIndex);
tree1.GetDiagnostics().Verify();
tree2.GetDiagnostics().Verify();
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs
index 1f9085b4ae8d2..2ff87944d57d0 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Immutable;
+using System.Linq;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Microsoft.CodeAnalysis.EditAndContinue;
using Microsoft.CodeAnalysis.EditAndContinue.UnitTests;
@@ -59,8 +60,7 @@ static void Goo()
new SourceLineUpdate(4, 9),
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(7),
new SourceLineUpdate(9, 4)
- },
- Array.Empty());
+ });
}
[Fact]
@@ -112,8 +112,7 @@ static int Bar()
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(8),
new SourceLineUpdate(10, 4),
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(13),
- },
- Array.Empty());
+ });
}
[Fact]
@@ -141,7 +140,7 @@ static void Bar()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- Array.Empty());
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Bar")) });
}
[Fact]
@@ -172,7 +171,7 @@ void F()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new[] { "void F()" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) });
}
[Fact]
@@ -199,8 +198,7 @@ static void Bar()
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(4, 6) },
- Array.Empty());
+ new[] { new SourceLineUpdate(4, 6) });
}
[Fact]
@@ -226,8 +224,7 @@ static void Bar()
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(4, 5) },
- Array.Empty());
+ new[] { new SourceLineUpdate(4, 5) });
}
[Fact]
@@ -254,8 +251,7 @@ class C
{
new SourceLineUpdate(3, 4),
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(4)
- },
- Array.Empty());
+ });
}
[Fact]
@@ -281,7 +277,7 @@ static void Bar()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "static void Bar()" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Bar")) });
}
[Fact]
@@ -307,8 +303,7 @@ static void Bar()
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(6, 5) },
- Array.Empty());
+ new[] { new SourceLineUpdate(6, 5) });
}
[Fact]
@@ -335,8 +330,7 @@ static void Bar()
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(5, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(5, 4) });
}
[Fact]
@@ -366,7 +360,7 @@ static void Bar()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "static void Bar()" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Bar")) });
var active = GetActiveStatements(src1, src2);
var syntaxMap = GetSyntaxMap(src1, src2);
@@ -388,7 +382,7 @@ class C { /*--*/static void Bar() { } }";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "static void Bar() { }" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Bar")) });
}
[Fact]
@@ -415,8 +409,7 @@ static void Bar()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(6, 5) },
- Array.Empty());
+ new[] { new SourceLineUpdate(6, 5) });
}
[Fact]
@@ -443,8 +436,7 @@ static void Bar()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "static void Bar()" },
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "\r\n /*edit*/", FeaturesResources.method));
+ diagnostics: new[] { Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "\r\n /*edit*/", FeaturesResources.method) });
}
[Fact]
@@ -471,8 +463,7 @@ static void Bar()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "static void Bar()" },
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "\r\n ", FeaturesResources.method));
+ diagnostics: new[] { Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "\r\n ", FeaturesResources.method) });
}
[Fact]
@@ -501,7 +492,7 @@ static async Task Bar()
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "static async Task Bar()" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Bar"), preserveLocalVariables: true) });
}
#endregion
@@ -541,8 +532,7 @@ public C(int a)
new SourceLineUpdate(4, 8),
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(6),
new SourceLineUpdate(8, 4)
- },
- Array.Empty());
+ });
}
[Fact]
@@ -568,8 +558,7 @@ public C(int a)
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(4, 5) },
- Array.Empty());
+ new[] { new SourceLineUpdate(4, 5) });
}
[Fact]
@@ -593,8 +582,7 @@ public C(int a) =>
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(5, 6) },
- Array.Empty());
+ new[] { new SourceLineUpdate(5, 6) });
}
[Fact]
@@ -618,8 +606,7 @@ public C(int a)
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(5, 6) },
- Array.Empty());
+ new[] { new SourceLineUpdate(5, 6) });
}
[Fact]
@@ -643,8 +630,7 @@ public C(int a) =>
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(5, 6) },
- Array.Empty());
+ new[] { new SourceLineUpdate(5, 6) });
}
[Fact]
@@ -671,8 +657,7 @@ public C(int a)
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(6, 8) },
- Array.Empty());
+ new[] { new SourceLineUpdate(6, 8) });
}
[Fact]
@@ -696,8 +681,7 @@ public C(int a)
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(5, 6) },
- Array.Empty());
+ new[] { new SourceLineUpdate(5, 6) });
}
[Fact]
@@ -722,8 +706,7 @@ public C(int a)
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new SourceLineUpdate[] { new(5, 6) },
- Array.Empty());
+ new SourceLineUpdate[] { new(5, 6) });
}
[Fact]
@@ -748,7 +731,7 @@ public C(int a)
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "public C(int a)" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true) });
}
[Fact]
@@ -774,8 +757,7 @@ public C(int a)
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new SourceLineUpdate[] { new(5, 6) },
- Array.Empty());
+ new SourceLineUpdate[] { new(5, 6) });
}
[Fact]
@@ -801,7 +783,7 @@ public C(int a)
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "public C(int a)" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true) });
}
[Fact]
@@ -827,8 +809,7 @@ public C(int a)
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "public C(int a)" },
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, " ", FeaturesResources.constructor));
+ diagnostics: new[] { Diagnostic(RudeEditKind.GenericTypeUpdate, "public C(int a)") });
}
#endregion
@@ -856,8 +837,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(5, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(5, 4) });
}
[Fact]
@@ -877,8 +857,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -898,8 +877,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
#endregion
@@ -923,8 +901,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- Array.Empty(),
- Array.Empty());
+ Array.Empty());
}
[Fact]
@@ -944,8 +921,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- Array.Empty(),
- Array.Empty());
+ Array.Empty());
}
[Fact]
@@ -966,8 +942,8 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4), new SourceLineUpdate(4, 3) },
- Array.Empty());
+ Array.Empty(),
+ diagnostics: new[] { Diagnostic(RudeEditKind.Move, "static int Bar = 2", FeaturesResources.field) });
}
[Fact]
@@ -989,8 +965,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 6) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 6) });
}
[Fact]
@@ -1011,7 +986,10 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new[] { "Bar = 2" });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -1031,8 +1009,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new SourceLineUpdate[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new SourceLineUpdate[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1053,7 +1030,10 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "Goo = " });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").StaticConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -1074,7 +1054,10 @@ static int Goo
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "Goo " });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").StaticConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -1095,7 +1078,10 @@ static int
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "Goo = 1" });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").StaticConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -1116,7 +1102,10 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "Goo = 1" });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").StaticConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -1137,7 +1126,10 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "Goo = 1" });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").StaticConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -1157,7 +1149,10 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "Goo = 1 + 1" });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").StaticConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -1177,8 +1172,10 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "Goo = 1 + 1" },
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, " ", FeaturesResources.field));
+ diagnostics: new[]
+ {
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "class C")
+ });
}
#endregion
@@ -1203,7 +1200,7 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "get { return " });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P").GetMethod) });
}
[Fact]
@@ -1222,9 +1219,7 @@ int P { get
{ return 1; } }
}";
var edits = GetTopEdits(src1, src2);
- edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ edits.VerifyLineEdits(new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1244,8 +1239,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1265,8 +1259,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1286,8 +1279,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1307,8 +1299,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1328,8 +1319,7 @@ int P {
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1349,8 +1339,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1370,7 +1359,7 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "int P { get; } = 1;" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true) });
}
#endregion
@@ -1395,7 +1384,7 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "get { return " });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.this[]").GetMethod) });
}
[Fact]
@@ -1414,9 +1403,7 @@ int this[int a] { get
{ return 1; } }
}";
var edits = GetTopEdits(src1, src2);
- edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ edits.VerifyLineEdits(new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1435,9 +1422,7 @@ class C
int this[int a] { get { return 1; } set { } }
}";
var edits = GetTopEdits(src1, src2);
- edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ edits.VerifyLineEdits(new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1457,8 +1442,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1478,8 +1462,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1499,8 +1482,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
#endregion
@@ -1524,8 +1506,7 @@ event Action E { add { } remove { } }
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(3, 4) },
- Array.Empty());
+ new[] { new SourceLineUpdate(3, 4) });
}
[Fact]
@@ -1546,7 +1527,7 @@ event Action E { add { } remove { } }
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
new[] { new SourceLineUpdate(4, 3) },
- new string[] { "add { }" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.E").AddMethod) });
}
[Fact]
@@ -1567,7 +1548,7 @@ event Action E { add { } remove { } }
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "remove { }" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.E").RemoveMethod) });
}
[Fact]
@@ -1587,8 +1568,7 @@ event Action E { add { } remove { } }
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(4, 3) },
- Array.Empty());
+ new[] { new SourceLineUpdate(4, 3) });
}
[Fact]
@@ -1610,7 +1590,7 @@ event Action E { add { } remove
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new[] { "remove " });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.E").RemoveMethod) });
}
[Fact, WorkItem(53263, "https://github.com/dotnet/roslyn/issues/53263")]
@@ -1632,7 +1612,7 @@ class C
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
new[] { new SourceLineUpdate(3, 4) },
- new[] { "remove => " });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.E").RemoveMethod) });
}
[Fact]
@@ -1653,8 +1633,7 @@ class C
}";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
- new[] { new SourceLineUpdate(4, 3), new SourceLineUpdate(5, 3) },
- Array.Empty());
+ new[] { new SourceLineUpdate(4, 3), new SourceLineUpdate(5, 3) });
}
#endregion
@@ -1697,8 +1676,7 @@ class C
new SourceLineUpdate(3, 9),
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(5),
new SourceLineUpdate(9, 3)
- },
- Array.Empty());
+ });
}
#endregion
@@ -1737,7 +1715,7 @@ static void F()
// Line deltas can't be applied on the whole breakpoint span hence recompilation.
edits.VerifyLineEdits(
Array.Empty(),
- new[] { "static void F()" });
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) });
}
///
@@ -1760,10 +1738,10 @@ class D
public D() {}
#line 5 ""a""
- public F3() {}
+ void F3() {}
#line 6 ""a""
- public F4() {}
+ void F4() {}
}";
var src2 = @"
#line 11 ""a""
@@ -1779,8 +1757,8 @@ class D
public D() {}
#line 5 ""a""
- public F3() {}
- public F4() {}
+ void F3() {}
+ void F4() {}
}
";
var edits = GetTopEdits(src1, src2);
@@ -1793,10 +1771,10 @@ public F4() {}
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(6), // lines between F2 and D ctor
new(9, 19))) // D ctor
},
- new[]
+ semanticEdits: new[]
{
- "public F3() {}", // overlaps with "void F1() { }"
- "public F4() {}" // overlaps with "void F2() { }"
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.F3")), // overlaps with "void F1() { }"
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.F4")), // overlaps with "void F2() { }"
});
}
@@ -1858,8 +1836,7 @@ static void F()
{
new("a", ImmutableArray.Create(new SourceLineUpdate(0, 1))),
new("b", ImmutableArray.Create(new SourceLineUpdate(0, 1))),
- },
- Array.Empty());
+ });
}
[Fact]
@@ -1901,12 +1878,10 @@ static void F()
{
new("a", ImmutableArray.Create(new SourceLineUpdate(6, 4))),
},
- expectedNodeUpdates: new[] { "static void F()" });
-
- edits.VerifySemantics(ActiveStatementsDescription.Empty, new[]
- {
- SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("F"))
- });
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"))
+ });
}
[Fact]
@@ -1923,8 +1898,10 @@ class C { static void Bar() { } }";
var edits = GetTopEdits(src1, src2);
edits.VerifyLineEdits(
Array.Empty(),
- new string[] { "static void Bar() { }" },
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "{", FeaturesResources.method));
+ diagnostics: new[]
+ {
+ Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "{", FeaturesResources.method)
+ });
}
#endregion
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs
index 27e7ed214b1a2..610c6ff3870b8 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs
@@ -1825,9 +1825,15 @@ interface I { void F() {} }
DocumentResults(
diagnostics: new[]
{
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "void F()", FeaturesResources.method),
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "void F()", FeaturesResources.method),
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "void F()", FeaturesResources.method),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "class C"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "struct S"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "interface I"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "void F()"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "void F()"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "void F()"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"),
})
});
}
@@ -3358,7 +3364,6 @@ public void EnumInitializerUpdate2()
"Update [Blue = 2]@22 -> [Blue = 2 << 1]@27");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.InitializerUpdate, "Red = 1 << 0", FeaturesResources.enum_value),
Diagnostic(RudeEditKind.InitializerUpdate, "Blue = 2 << 1", FeaturesResources.enum_value));
}
@@ -3855,7 +3860,8 @@ public void Delegates_TypeParameter_Rename()
"Update [T]@22 -> [S]@22");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Renamed, "S", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.Renamed, "S", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"));
}
[Fact]
@@ -3870,7 +3876,8 @@ public void Delegates_TypeParameter_Variance1()
"Update [T]@22 -> [in T]@22");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -3885,7 +3892,8 @@ public void Delegates_TypeParameter_Variance2()
"Update [out T]@22 -> [T]@22");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -3900,7 +3908,8 @@ public void Delegates_TypeParameter_Variance3()
"Update [out T]@22 -> [in T]@22");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -3916,13 +3925,9 @@ public void Delegates_TypeParameter_AddAttribute()
edits.VerifyEdits(
"Update [T]@70 -> [[A]T]@70");
- edits.VerifySemantics(
- ActiveStatementsDescription.Empty,
- new[]
- {
- SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D")),
- },
- capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
+ edits.VerifyRudeDiagnostics(
+ EditAndContinueTestHelpers.Net6RuntimeCapabilities,
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -4614,7 +4619,9 @@ public void NestedPartialTypeInPartialType_InsertDeleteAndChange_TypeParameterAt
DocumentResults(
diagnostics: new[]
{
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter)
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "partial class C<[A]T>"),
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T")
}),
DocumentResults(),
@@ -4641,7 +4648,9 @@ public void NestedPartialTypeInPartialType_InsertDeleteAndChange_Constraint()
DocumentResults(
diagnostics: new[]
{
- Diagnostic(RudeEditKind.ChangingConstraints, "where T : new()", FeaturesResources.type_parameter)
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "partial class C"),
+ Diagnostic(RudeEditKind.ChangingConstraints, "where T : new()", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : new()")
}),
DocumentResults(),
@@ -5077,8 +5086,8 @@ public void PartialMember_DeleteInsert_GenericMethod()
DocumentResults(),
DocumentResults(diagnostics: new[]
{
- // TODO: better message
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "void F()", FeaturesResources.method)
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "void F()"),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T")
})
});
}
@@ -5098,8 +5107,7 @@ public void PartialMember_DeleteInsert_GenericType()
DocumentResults(),
DocumentResults(diagnostics: new[]
{
- // TODO: better message
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "void F()", FeaturesResources.method)
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "void F()")
})
});
}
@@ -7446,19 +7454,14 @@ public void PartialMethod_Swap_ImplementationAndDefinitionParts()
var srcA2 = "partial class C { partial void F() { } }";
var srcB2 = "partial class C { partial void F(); }";
- // current:
- GetTopEdits(srcA1, srcA2).VerifyRudeDiagnostics(Diagnostic(RudeEditKind.MethodBodyAdd, "partial void F()", FeaturesResources.method));
- GetTopEdits(srcB1, srcB2).VerifyRudeDiagnostics(Diagnostic(RudeEditKind.MethodBodyDelete, "partial void F()", FeaturesResources.method));
-
- // correct: TODO
- //EditAndContinueValidation.VerifySemantics(
- // new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
- // new[]
- // {
- // DocumentResults(),
- // DocumentResults(
- // semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("F")) }),
- // });
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(
+ semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("F").PartialImplementationPart) }),
+ DocumentResults(),
+ });
}
[Fact]
@@ -7575,7 +7578,19 @@ public void Operator_Conversion_ExternModifiers_Add()
var edits = GetTopEdits(src1, src2);
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.MethodBodyDelete, "extern public static implicit operator bool (C c)", CSharpFeaturesResources.conversion_operator));
+ Diagnostic(RudeEditKind.ModifiersUpdate, "extern public static implicit operator bool (C c)", CSharpFeaturesResources.conversion_operator));
+ }
+
+ [Fact]
+ public void Operator_Conversion_ExternModifiers_Remove()
+ {
+ var src1 = "class C { extern public static implicit operator bool (C c); }";
+ var src2 = "class C { public static implicit operator bool (C c) => default; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "public static implicit operator bool (C c)", CSharpFeaturesResources.conversion_operator));
}
[Fact]
@@ -7864,8 +7879,9 @@ public void Constructor_ExternModifier_Add()
"Insert [public extern C();]@10",
"Insert [()]@25");
- // The compiler generates an empty constructor.
- edits.VerifySemanticDiagnostics();
+ // This can be allowed as the compiler generates an empty constructor, but it's not worth the complexity.
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "public extern C()", FeaturesResources.constructor));
}
[Fact]
@@ -7908,7 +7924,7 @@ public C(int a) { }
"Update [public C(int a) : base(a) { }]@21 -> [public C(int a) { }]@21");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericTypeUpdate, "public C(int a)", FeaturesResources.constructor));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "public C(int a)"));
}
[Fact]
@@ -7951,7 +7967,7 @@ public C(int a) : base(a + 1) { }
"Update [public C(int a) : base(a) { }]@21 -> [public C(int a) : base(a + 1) { }]@21");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericTypeUpdate, "public C(int a)", FeaturesResources.constructor));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "public C(int a)"));
}
[WorkItem(743552, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/743552")]
@@ -9352,8 +9368,31 @@ public void PropertyInitializer_Update2()
"Update [int a { get; } = 0;]@10 -> [int a { get { return 1; } }]@10",
"Update [get;]@18 -> [get { return 1; }]@18");
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.MethodBodyAdd, "get", CSharpFeaturesResources.property_getter));
+ edits.VerifySemantics(
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(), preserveLocalVariables: true));
+ }
+
+ [Fact]
+ public void PropertyInitializer_InsertDelete()
+ {
+ var srcA1 = "partial class C { }";
+ var srcB1 = "partial class C { int a { get; } = 0; }";
+ var srcA2 = "partial class C { int a { get { return 1; } } }";
+ var srcB2 = "partial class C { }";
+
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(), partialType: "C", preserveLocalVariables: true)
+ }),
+ DocumentResults()
+ });
}
[Fact]
@@ -9384,8 +9423,13 @@ public void PropertyInitializer_Update3()
"Update [int a { get { return 1; } }]@10 -> [int a { get; } = 0;]@10",
"Update [get { return 1; }]@18 -> [get;]@18");
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.MethodBodyDelete, "get", CSharpFeaturesResources.property_getter));
+ edits.VerifySemantics(
+ ActiveStatementsDescription.Empty,
+ new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true)
+ });
}
[Fact]
@@ -9701,7 +9745,8 @@ public void FieldInitializerUpdate_GenericType()
"Update [a = 1]@17 -> [a = 2]@17");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericTypeInitializerUpdate, "a = 2", FeaturesResources.field));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "a = 2"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "class C"));
}
[Fact]
@@ -9713,7 +9758,8 @@ public void PropertyInitializerUpdate_GenericType()
var edits = GetTopEdits(src1, src2);
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericTypeInitializerUpdate, "int a", FeaturesResources.auto_property));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "int a"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "class C"));
}
[Fact]
@@ -10905,15 +10951,18 @@ public void Field_Attribute_Add_InsertDelete()
[Fact]
public void Field_FixedSize_Update()
{
- var src1 = "struct S { public unsafe fixed byte bs[1]; }";
- var src2 = "struct S { public unsafe fixed byte bs[2]; }";
+ var src1 = "struct S { public unsafe fixed byte a[1], b[2]; }";
+ var src2 = "struct S { public unsafe fixed byte a[2], b[3]; }";
var edits = GetTopEdits(src1, src2);
- edits.VerifyEdits("Update [bs[1]]@36 -> [bs[2]]@36");
+ edits.VerifyEdits(
+ "Update [a[1]]@36 -> [a[2]]@36",
+ "Update [b[2]]@42 -> [b[3]]@42");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.FixedSizeFieldUpdate, "bs[2]", FeaturesResources.field));
+ Diagnostic(RudeEditKind.FixedSizeFieldUpdate, "a[2]", FeaturesResources.field),
+ Diagnostic(RudeEditKind.FixedSizeFieldUpdate, "b[3]", FeaturesResources.field));
}
[WorkItem(1120407, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1120407")]
@@ -10928,7 +10977,7 @@ public void Field_Const_Update()
edits.VerifyEdits("Update [x = 0]@20 -> [x = 1]@20");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Update, "x = 1", FeaturesResources.const_field));
+ Diagnostic(RudeEditKind.InitializerUpdate, "x = 1", FeaturesResources.const_field));
}
[Fact]
@@ -14398,8 +14447,9 @@ public void MethodTypeParameter_Attribute_Insert1()
"Update [T]@72 -> [[A]T]@72");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method),
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T"),
+ Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method));
}
[Fact]
@@ -14417,8 +14467,9 @@ public void MethodTypeParameter_Attribute_Insert2()
"Update [[A]T]@120 -> [[A, B]T]@120");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method),
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T"),
+ Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method));
}
[Fact]
@@ -14435,8 +14486,9 @@ public void MethodTypeParameter_Attribute_Delete()
"Update [[A]T]@72 -> [T]@72");
edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method),
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T"));
}
[Fact]
@@ -14454,7 +14506,8 @@ public void MethodTypeParameter_Attribute_Update_NotSupportedByRuntime()
"Update [[System.Obsolete(\"1\"), B]T]@120 -> [[System.Obsolete(\"2\"), A]T]@120");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T"));
}
[Fact]
@@ -14470,10 +14523,9 @@ public void MethodTypeParameter_Attribute_Update()
edits.VerifyEdits(
"Update [[A(0)]T]@67 -> [[A(1)]T]@67");
- edits.VerifySemantics(
- ActiveStatementsDescription.Empty,
- new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) },
- capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
+ edits.VerifyRudeDiagnostics(
+ EditAndContinueTestHelpers.Net6RuntimeCapabilities,
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T"));
}
[Fact]
@@ -14491,8 +14543,9 @@ public void MethodTypeParameter_Attribute_Update_WithBodyUpdate()
"Update [[A(0)]T]@67 -> [[A(1)]T]@67");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericMethodUpdate, "void F<[A(1)]T>(T a)", FeaturesResources.method),
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "void F<[A(1)]T>(T a)"),
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T"));
}
#endregion
@@ -14571,7 +14624,8 @@ public void TypeTypeParameterUpdate()
"Update [A]@8 -> [B]@8");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Renamed, "B", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.Renamed, "B", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "B"));
}
[Fact]
@@ -14603,7 +14657,8 @@ public void TypeTypeParameterReorderAndUpdate()
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.Move, "B", FeaturesResources.type_parameter),
- Diagnostic(RudeEditKind.Renamed, "C", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.Renamed, "C", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "C"));
}
[Fact]
@@ -14620,7 +14675,8 @@ public void TypeTypeParameterAttributeInsert1()
"Update [T]@56 -> [[A]T]@56");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -14638,7 +14694,8 @@ public void TypeTypeParameterAttributeInsert2()
"Update [[A]T]@104 -> [[A, B]T]@104");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -14654,10 +14711,9 @@ public void TypeTypeParameterAttributeInsert_SupportedByRuntime()
edits.VerifyEdits(
"Update [T]@56 -> [[A]T]@56");
- edits.VerifySemantics(
- ActiveStatementsDescription.Empty,
- new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C")) },
- capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
+ edits.VerifyRudeDiagnostics(
+ EditAndContinueTestHelpers.Net6RuntimeCapabilities,
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -14674,7 +14730,8 @@ public void TypeTypeParameterAttributeDelete()
"Update [[A]T]@56 -> [T]@56");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Fact]
@@ -14692,7 +14749,8 @@ public void TypeTypeParameterAttributeUpdate()
"Update [[System.Obsolete(\"1\"), B]T]@104 -> [[System.Obsolete(\"2\"), A]T]@104");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
#endregion
@@ -14718,7 +14776,8 @@ public void TypeConstraint_Insert(string newConstraint)
"Insert [where T : " + newConstraint + "]@13");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "where T : " + newConstraint, FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingConstraints, "where T : " + newConstraint, FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : " + newConstraint));
}
[Theory]
@@ -14740,7 +14799,8 @@ public void TypeConstraint_Delete(string oldConstraint)
"Delete [where T : " + oldConstraint + "]@13");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"));
}
[Theory]
@@ -14754,8 +14814,8 @@ public void TypeConstraint_Update_RuntimeTypeUnchanged(string oldType, string ne
var edits = GetTopEdits(src1, src2);
- edits.VerifySemantics(
- SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C")));
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : System.Collections.Generic.List<" + newType + ">"));
}
[Theory]
@@ -14770,7 +14830,8 @@ public void TypeConstraint_Update_RuntimeTypeChanged(string oldType, string newT
var edits = GetTopEdits(src1, src2);
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "where T : System.Collections.Generic.List<" + newType + ">", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingConstraints, "where T : System.Collections.Generic.List<" + newType + ">", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : System.Collections.Generic.List<" + newType + ">"));
}
[Fact]
@@ -14797,7 +14858,8 @@ public void TypeConstraint_MultipleClauses_Insert()
"Insert [where S : unmanaged]@13");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "where S : unmanaged", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingConstraints, "where S : unmanaged", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "where S : unmanaged"));
}
[Fact]
@@ -14812,7 +14874,8 @@ public void TypeConstraint_MultipleClauses_Delete()
"Delete [where S : new()]@13");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"));
}
[Fact]
@@ -14846,7 +14909,9 @@ public void TypeConstraint_MultipleClauses_UpdateAndReorder()
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.Move, "T", FeaturesResources.type_parameter),
Diagnostic(RudeEditKind.ChangingConstraints, "where T : class, I", FeaturesResources.type_parameter),
- Diagnostic(RudeEditKind.ChangingConstraints, "where S : class, new()", FeaturesResources.type_parameter));
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : class, I"),
+ Diagnostic(RudeEditKind.ChangingConstraints, "where S : class, new()", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "where S : class, new()"));
}
#endregion
diff --git a/src/EditorFeatures/Test/EditAndContinue/RudeEditDiagnosticTests.cs b/src/EditorFeatures/Test/EditAndContinue/RudeEditDiagnosticTests.cs
index 6cb4b1af0b2ae..3ab0c795fd1a9 100644
--- a/src/EditorFeatures/Test/EditAndContinue/RudeEditDiagnosticTests.cs
+++ b/src/EditorFeatures/Test/EditAndContinue/RudeEditDiagnosticTests.cs
@@ -37,8 +37,6 @@ public void ToDiagnostic()
RudeEditKind.DeclareLibraryUpdate,
RudeEditKind.DeclareAliasUpdate,
RudeEditKind.InsertDllImport,
- RudeEditKind.MethodBodyAdd,
- RudeEditKind.MethodBodyDelete,
RudeEditKind.GenericMethodUpdate,
RudeEditKind.GenericTypeUpdate,
RudeEditKind.ExperimentalFeaturesEnabled,
diff --git a/src/EditorFeatures/TestUtilities/EditAndContinue/DocumentAnalysisResultsDescription.cs b/src/EditorFeatures/TestUtilities/EditAndContinue/DocumentAnalysisResultsDescription.cs
index bb569665adeb3..549ee0fd6b8bc 100644
--- a/src/EditorFeatures/TestUtilities/EditAndContinue/DocumentAnalysisResultsDescription.cs
+++ b/src/EditorFeatures/TestUtilities/EditAndContinue/DocumentAnalysisResultsDescription.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Immutable;
+using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue;
namespace Microsoft.CodeAnalysis.EditAndContinue.UnitTests
{
@@ -15,14 +16,17 @@ internal readonly struct DocumentAnalysisResultsDescription
///
public readonly ImmutableArray SemanticEdits;
+ public readonly ImmutableArray LineEdits;
+
public readonly ImmutableArray Diagnostics;
public DocumentAnalysisResultsDescription(
ActiveStatementsDescription? activeStatements = null,
SemanticEditDescription[]? semanticEdits = null,
+ SequencePointUpdates[]? lineEdits = null,
RudeEditDiagnosticDescription[]? diagnostics = null)
{
- // The test must validate semantic edits, diagnostics or both.
+ // The test must validate semantic edits, lineEdits, diagnostics or all of the above.
// If neither is specified then assume the expectation is that
// the documents has no edits and no diagnostics.
if (semanticEdits is null && diagnostics is null)
@@ -36,6 +40,7 @@ public DocumentAnalysisResultsDescription(
Diagnostics = diagnostics.AsImmutableOrEmpty();
}
+ LineEdits = lineEdits.AsImmutableOrNull();
ActiveStatements = activeStatements ?? ActiveStatementsDescription.Empty;
}
}
diff --git a/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs b/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs
index c016d6cc6552d..8c4f13303c736 100644
--- a/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs
+++ b/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs
@@ -81,48 +81,15 @@ private void VerifyDocumentActiveStatementsAndExceptionRegions(
internal void VerifyLineEdits(
EditScript editScript,
- IEnumerable expectedLineEdits,
- IEnumerable expectedNodeUpdates,
- RudeEditDiagnosticDescription[] expectedDiagnostics)
+ SequencePointUpdates[] expectedLineEdits,
+ SemanticEditDescription[]? expectedSemanticEdits,
+ RudeEditDiagnosticDescription[]? expectedDiagnostics)
{
- var newText = SourceText.From(editScript.Match.NewRoot.SyntaxTree.ToString());
-
- var diagnostics = new ArrayBuilder();
- var editMap = BuildEditMap(editScript);
-
- var triviaEdits = new ArrayBuilder<(SyntaxNode OldNode, SyntaxNode NewNode)>();
- var actualLineEdits = new ArrayBuilder();
-
- Analyzer.GetTestAccessor().AnalyzeTrivia(
- editScript.Match,
- editMap,
- triviaEdits,
- actualLineEdits,
- diagnostics,
- default);
-
- VerifyDiagnostics(expectedDiagnostics, diagnostics, newText);
-
- // check files are matching:
- AssertEx.Equal(
- expectedLineEdits.Select(e => e.FileName),
- actualLineEdits.Select(e => e.FileName),
- itemSeparator: ",\r\n");
-
- // check lines are matching:
- _ = expectedLineEdits.Zip(actualLineEdits, (expected, actual) =>
- {
- AssertEx.Equal(
- expected.LineUpdates,
- actual.LineUpdates,
- itemSeparator: ",\r\n",
- itemInspector: s => $"new({s.OldLine}, {s.NewLine})");
-
- return true;
- }).ToArray();
-
- var actualNodeUpdates = triviaEdits.Select(e => e.NewNode.ToString().ToLines().First());
- AssertEx.Equal(expectedNodeUpdates, actualNodeUpdates, itemSeparator: ",\r\n");
+ VerifySemantics(
+ new[] { editScript },
+ TargetFramework.NetStandard20,
+ new[] { new DocumentAnalysisResultsDescription(semanticEdits: expectedSemanticEdits, lineEdits: expectedLineEdits, diagnostics: expectedDiagnostics) },
+ capabilities: Net5RuntimeCapabilities);
}
internal void VerifySemantics(EditScript[] editScripts, TargetFramework targetFramework, DocumentAnalysisResultsDescription[] expectedResults, EditAndContinueCapabilities? capabilities = null)
@@ -205,6 +172,34 @@ internal void VerifySemantics(EditScript[] editScripts, TargetFramew
result.ActiveStatements,
result.ExceptionRegions);
}
+
+ if (!result.RudeEditErrors.IsEmpty)
+ {
+ Assert.True(result.LineEdits.IsDefault);
+ Assert.True(expectedResult.LineEdits.IsDefaultOrEmpty);
+ }
+ else if (!expectedResult.LineEdits.IsDefault)
+ {
+ // check files of line edits:
+ AssertEx.Equal(
+ expectedResult.LineEdits.Select(e => e.FileName),
+ result.LineEdits.Select(e => e.FileName),
+ itemSeparator: ",\r\n",
+ message: "File names of line edits differ in " + assertMessagePrefix);
+
+ // check lines of line edits:
+ _ = expectedResult.LineEdits.Zip(result.LineEdits, (expected, actual) =>
+ {
+ AssertEx.Equal(
+ expected.LineUpdates,
+ actual.LineUpdates,
+ itemSeparator: ",\r\n",
+ itemInspector: s => $"new({s.OldLine}, {s.NewLine})",
+ message: "Line deltas differ in " + assertMessagePrefix);
+
+ return true;
+ }).ToArray();
+ }
}
// check if we can merge edits without throwing:
diff --git a/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditAndContinueValidation.vb b/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditAndContinueValidation.vb
index 2e153ed184fe0..c540b86ec0dd5 100644
--- a/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditAndContinueValidation.vb
+++ b/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditAndContinueValidation.vb
@@ -28,25 +28,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue.UnitTests
Friend Sub VerifyLineEdits(editScript As EditScript(Of SyntaxNode),
- expectedLineEdits As IEnumerable(Of SourceLineUpdate),
- expectedNodeUpdates As IEnumerable(Of String),
- ParamArray expectedDiagnostics As RudeEditDiagnosticDescription())
- Assert.NotEmpty(expectedLineEdits)
+ lineEdits As SourceLineUpdate(),
+ Optional semanticEdits As SemanticEditDescription() = Nothing,
+ Optional diagnostics As RudeEditDiagnosticDescription() = Nothing)
+ Assert.NotEmpty(lineEdits)
VerifyLineEdits(
editScript,
- {New SequencePointUpdates(editScript.Match.OldRoot.SyntaxTree.FilePath, expectedLineEdits.ToImmutableArray())},
- expectedNodeUpdates,
- expectedDiagnostics)
+ {New SequencePointUpdates(editScript.Match.OldRoot.SyntaxTree.FilePath, lineEdits.ToImmutableArray())},
+ semanticEdits,
+ diagnostics)
End Sub
Friend Sub VerifyLineEdits(editScript As EditScript(Of SyntaxNode),
- expectedLineEdits As IEnumerable(Of SequencePointUpdates),
- expectedNodeUpdates As IEnumerable(Of String),
- ParamArray expectedDiagnostics As RudeEditDiagnosticDescription())
+ lineEdits As SequencePointUpdates(),
+ Optional semanticEdits As SemanticEditDescription() = Nothing,
+ Optional diagnostics As RudeEditDiagnosticDescription() = Nothing)
Dim validator = New VisualBasicEditAndContinueTestHelpers()
- validator.VerifyLineEdits(editScript, expectedLineEdits, expectedNodeUpdates, expectedDiagnostics)
+ validator.VerifyLineEdits(editScript, lineEdits, semanticEdits, diagnostics)
End Sub
@@ -76,7 +76,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue.UnitTests
Optional capabilities As EditAndContinueCapabilities? = Nothing)
VerifySemantics(
{editScript},
- {New DocumentAnalysisResultsDescription(activeStatements, semanticEdits, diagnostics)},
+ {New DocumentAnalysisResultsDescription(activeStatements, semanticEdits, lineEdits:=Nothing, diagnostics)},
targetFrameworks,
capabilities)
End Sub
diff --git a/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditingTestBase.vb b/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditingTestBase.vb
index 5a6a8a423c7ee..062db44057304 100644
--- a/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditingTestBase.vb
+++ b/src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/EditingTestBase.vb
@@ -82,19 +82,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue.UnitTests
Optional activeStatements As ActiveStatementsDescription = Nothing,
Optional semanticEdits As SemanticEditDescription() = Nothing,
Optional diagnostics As RudeEditDiagnosticDescription() = Nothing) As DocumentAnalysisResultsDescription
- Return New DocumentAnalysisResultsDescription(activeStatements, semanticEdits, diagnostics)
+ Return New DocumentAnalysisResultsDescription(activeStatements, semanticEdits, lineEdits:=Nothing, diagnostics)
End Function
- Private Shared Function ParseSource(markedSource As String) As SyntaxTree
+ Private Shared Function ParseSource(markedSource As String, Optional documentIndex As Integer = 0) As SyntaxTree
Return SyntaxFactory.ParseSyntaxTree(
ActiveStatementsDescription.ClearTags(markedSource),
VisualBasicParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest),
- path:="test.vb")
+ path:=documentIndex.ToString())
End Function
- Friend Shared Function GetTopEdits(src1 As String, src2 As String) As EditScript(Of SyntaxNode)
- Dim tree1 = ParseSource(src1)
- Dim tree2 = ParseSource(src2)
+ Friend Shared Function GetTopEdits(src1 As String, src2 As String, Optional documentIndex As Integer = 0) As EditScript(Of SyntaxNode)
+ Dim tree1 = ParseSource(src1, documentIndex)
+ Dim tree2 = ParseSource(src2, documentIndex)
tree1.GetDiagnostics().Verify()
tree2.GetDiagnostics().Verify()
diff --git a/src/EditorFeatures/VisualBasicTest/EditAndContinue/LineEditTests.vb b/src/EditorFeatures/VisualBasicTest/EditAndContinue/LineEditTests.vb
index a3b70d11715e1..4f9a5ed622202 100644
--- a/src/EditorFeatures/VisualBasicTest/EditAndContinue/LineEditTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/EditAndContinue/LineEditTests.vb
@@ -38,7 +38,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), Array.Empty(Of String))
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"))})
End Sub
@@ -190,7 +192,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Shared Sub _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ semanticEdits:={SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"))})
End Sub
@@ -212,7 +216,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Shared Sub Bar()"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ semanticEdits:={SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"))})
End Sub
@@ -286,13 +292,16 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Shared Sub Bar()"})
-
Dim active = GetActiveStatements(src1, src2)
Dim syntaxMap = GetSyntaxMap(src1, src2)
- edits.VerifySemantics(active,
- {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"), syntaxMap(0))})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"))})
+
+ edits.VerifySemantics(
+ active,
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"), syntaxMap:=syntaxMap(0))})
End Sub
@@ -310,7 +319,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Shared Sub Bar() : End Sub"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"))})
End Sub
@@ -333,8 +344,8 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits({New SourceLineUpdate(4, 3)},
- Array.Empty(Of String))
+ edits.VerifyLineEdits(
+ {New SourceLineUpdate(4, 3)})
End Sub
@@ -355,9 +366,9 @@ Class C(Of T)
End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates),
- {"Shared Sub Bar()"},
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, vbCrLf & " ", FeaturesResources.method))
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ diagnostics:={Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, vbCrLf & " ", FeaturesResources.method)})
End Sub
@@ -379,9 +390,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates),
- {"Shared Sub Bar(Of T)()"},
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, vbCrLf & " ", FeaturesResources.method))
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ diagnostics:={Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, vbCrLf & " ", FeaturesResources.method)})
End Sub
@@ -404,8 +415,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates),
- {"Shared Async Function Bar() As Task(Of Integer)"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.Bar"), preserveLocalVariables:=True)})
End Sub
#End Region
@@ -430,7 +442,9 @@ End Class"
End Class"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Shared Sub _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").SharedConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -451,7 +465,9 @@ End Class"
End Class"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Shared Sub _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").SharedConstructors.Single())})
End Sub
#End Region
@@ -473,7 +489,9 @@ Class C
End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits({New SourceLineUpdate(2, 3), New SourceLineUpdate(3, 2)}, {})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ diagnostics:={Diagnostic(RudeEditKind.Move, "Shared Bar As Integer = 2", FeaturesResources.field)})
End Sub
@@ -491,7 +509,9 @@ Class C
End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits({New SourceLineUpdate(2, 3), New SourceLineUpdate(3, 2)}, {})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ diagnostics:={Diagnostic(RudeEditKind.Move, "Shared c As New C()", FeaturesResources.field)})
End Sub
@@ -511,8 +531,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits({New SourceLineUpdate(2, 3),
- New SourceLineUpdate(3, 2)}, {})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ diagnostics:={Diagnostic(RudeEditKind.Move, "Shared c, d As New C()", FeaturesResources.field)})
End Sub
@@ -606,7 +627,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits({New SourceLineUpdate(2, 3)}, {"Goo"})
+ edits.VerifyLineEdits(
+ {New SourceLineUpdate(2, 3)},
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -662,7 +685,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo = _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -681,7 +706,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo _ "})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -700,7 +727,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -718,7 +747,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo = 1"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -736,7 +767,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo As Integer = 1 + 1"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -755,7 +788,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo As _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -774,7 +809,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -795,7 +832,9 @@ End Class
Dim edits = GetTopEdits(src1, src2)
' to make it simpler, we recompile the constructor (by reporting a field as a node update)
- edits.VerifyLineEdits({New SourceLineUpdate(2, 3)}, {"Goo"})
+ edits.VerifyLineEdits(
+ {New SourceLineUpdate(2, 3)},
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -815,7 +854,9 @@ End Class
Dim edits = GetTopEdits(src1, src2)
' we treat "Goo + New D()" as a whole for simplicity
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo", "Bar"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -833,7 +874,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo", "Bar"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -852,7 +895,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo", "Bar"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -869,7 +914,9 @@ Class C
End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Goo(1)"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -887,9 +934,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates),
- {"Goo As Integer = 1 + 1"},
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, " ", FeaturesResources.field))
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ diagnostics:={Diagnostic(RudeEditKind.GenericTypeUpdate, "Class C(Of T)")})
End Sub
#End Region
@@ -1043,7 +1090,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Property Goo _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -1062,7 +1111,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Property Goo As _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -1081,7 +1132,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Property Goo As Integer _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -1100,7 +1153,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Property Goo As Integer = _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -1119,7 +1174,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Property Goo As _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
@@ -1138,7 +1195,9 @@ End Class
"
Dim edits = GetTopEdits(src1, src2)
- edits.VerifyLineEdits(Array.Empty(Of SequencePointUpdates), {"Property Goo$ = _"})
+ edits.VerifyLineEdits(
+ Array.Empty(Of SequencePointUpdates),
+ {SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single(), preserveLocalVariables:=True)})
End Sub
#End Region
@@ -1195,9 +1254,10 @@ End Class
AbstractEditAndContinueAnalyzer.CreateZeroDeltaSourceLineUpdate(5),' lines between F2 And D ctor
New SourceLineUpdate(7, 17)))' D ctor
},
+ semanticEdits:=
{
- "Sub F3() : End Sub", ' overlaps with "Sub F1"
- "Sub F4() : End Sub" ' overlaps with "Sub F2"
+ SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("D.F3")),
+ SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("D.F4"))
})
End Sub
@@ -1257,8 +1317,7 @@ End Class"
{
New SequencePointUpdates("a", ImmutableArray.Create(New SourceLineUpdate(0, 1))),
New SequencePointUpdates("b", ImmutableArray.Create(New SourceLineUpdate(0, 1)))
- },
- Array.Empty(Of String))
+ })
End Sub
@@ -1298,7 +1357,7 @@ End Class"
{
New SequencePointUpdates("a", ImmutableArray.Create(New SourceLineUpdate(6, 4)))
},
- {"Sub F()"})
+ semanticEdits:={SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.F"))})
edits.VerifySemantics(ActiveStatementsDescription.Empty,
{
@@ -1328,8 +1387,7 @@ End Class
Dim edits = GetTopEdits(src1, src2)
edits.VerifyLineEdits(
Array.Empty(Of SequencePointUpdates)(),
- {"Sub Bar(Of T)()"},
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "Sub Bar(Of T)()", FeaturesResources.method))
+ diagnostics:={Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "Sub Bar(Of T)()", FeaturesResources.method)})
End Sub
#End Region
diff --git a/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb b/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb
index d0750b0576f5e..76ea68af92414 100644
--- a/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb
@@ -1061,7 +1061,8 @@ End Class"
Diagnostic(RudeEditKind.InsertIntoGenericType, "F4 As New Object", FeaturesResources.field),
Diagnostic(RudeEditKind.InsertIntoGenericType, "F5(1, 2)", FeaturesResources.field),
Diagnostic(RudeEditKind.InsertIntoGenericType, "F6?", FeaturesResources.field),
- Diagnostic(RudeEditKind.InsertIntoGenericType, "WE As Object", VBFeaturesResources.WithEvents_field))
+ Diagnostic(RudeEditKind.InsertIntoGenericType, "WE As Object", VBFeaturesResources.WithEvents_field),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Class C(Of T)"))
End Sub
@@ -1253,9 +1254,15 @@ End Interface
DocumentResults(
diagnostics:=
{
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "Sub F()", FeaturesResources.method),
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "Sub F()", FeaturesResources.method),
- Diagnostic(RudeEditKind.GenericTypeTriviaUpdate, "Sub F()", FeaturesResources.method)
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Class C(Of T)"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Structure S(Of T)"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Interface I(Of T)"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Sub F()"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Sub F()"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Sub F()"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T")
})
})
End Sub
@@ -1574,21 +1581,20 @@ End Class
"Update [Blue = 2]@23 -> [Blue = 2 << 1]@28")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.InitializerUpdate, "Red = 1 << 0", FeaturesResources.enum_value),
Diagnostic(RudeEditKind.InitializerUpdate, "Blue = 2 << 1", FeaturesResources.enum_value))
End Sub
Public Sub Enum_MemberInitializer_Update3()
- Dim src1 = "Enum Color : Red = int.MinValue : End Enum"
- Dim src2 = "Enum Color : Red = int.MaxValue : End Enum"
+ Dim src1 = "Enum Color : Red = Integer.MinValue : End Enum"
+ Dim src2 = "Enum Color : Red = Integer.MaxValue : End Enum"
Dim edits = GetTopEdits(src1, src2)
edits.VerifyEdits(
- "Update [Red = int.MinValue]@13 -> [Red = int.MaxValue]@13")
+ "Update [Red = Integer.MinValue]@13 -> [Red = Integer.MaxValue]@13")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.InitializerUpdate, "Red = int.MaxValue", FeaturesResources.enum_value))
+ Diagnostic(RudeEditKind.InitializerUpdate, "Red = Integer.MaxValue", FeaturesResources.enum_value))
End Sub
@@ -1886,7 +1892,8 @@ End Class
"Update [T]@30 -> [S]@30")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Renamed, "S", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.Renamed, "S", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"))
End Sub
@@ -1899,7 +1906,8 @@ End Class
"Update [T]@30 -> [In T]@30")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"))
End Sub
@@ -1912,7 +1920,8 @@ End Class
"Update [Out T]@30 -> [T]@30")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"))
End Sub
@@ -1925,7 +1934,8 @@ End Class
"Update [Out T]@30 -> [In T]@30")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"))
End Sub
@@ -2497,7 +2507,12 @@ End Structure
{
DocumentResults(),
DocumentResults(
- diagnostics:={Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter)}),
+ diagnostics:=
+ {
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Partial Class C(Of T As New)"),
+ Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T")
+ }),
DocumentResults()
})
End Sub
@@ -2804,14 +2819,14 @@ End Class
Dim srcA2 = "Partial Class C : End Class"
Dim srcB2 = "Partial Class C" + vbCrLf + "Sub F(Of T)() : End Sub : End Class"
- ' TODO better message
EditAndContinueValidation.VerifySemantics(
{GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2)},
{
DocumentResults(),
DocumentResults(diagnostics:=
{
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "Sub F(Of T)()", FeaturesResources.method)
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "Sub F(Of T)()"),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T")
})
})
End Sub
@@ -2830,7 +2845,8 @@ End Class
DocumentResults(),
DocumentResults(diagnostics:=
{
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "Sub F(Of T)()", FeaturesResources.method)
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "Sub F(Of T)()"),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "T")
})
})
End Sub
@@ -3893,12 +3909,48 @@ End Class
Public Sub MethodUpdate_ImplementsDelete()
- Dim src1 = "Class C : Implements I, J : " & vbLf & "Sub Goo Implements I.Goo : End Sub : " & vbLf & "Sub JGoo Implements J.Goo : End Sub : End Class"
- Dim src2 = "Class C : Implements I, J : " & vbLf & "Sub Goo : End Sub : " & vbLf & "Sub JGoo Implements J.Goo : End Sub : End Class"
+ Dim src1 = "
+Class C
+ Implements I, J
+
+ Sub Goo Implements I.Goo
+ End Sub
+
+ Sub JGoo Implements J.Goo
+ End Sub
+End Class
+
+Interface I
+ Sub Goo
+End Interface
+
+Interface J
+ Sub Goo
+End Interface
+"
+ Dim src2 = "
+Class C
+ Implements I, J
+
+ Sub Goo
+ End Sub
+
+ Sub JGoo Implements J.Goo
+ End Sub
+End Class
+
+Interface I
+ Sub Goo
+End Interface
+
+Interface J
+ Sub Goo
+End Interface
+"
Dim edits = GetTopEdits(src1, src2)
edits.VerifyEdits(
- "Update [Sub Goo Implements I.Goo]@29 -> [Sub Goo]@29")
+ "Update [Sub Goo Implements I.Goo]@39 -> [Sub Goo]@39")
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.ImplementsClauseUpdate, "Sub Goo", FeaturesResources.method))
@@ -3906,12 +3958,49 @@ End Class
Public Sub MethodUpdate_ImplementsInsert()
- Dim src1 = "Class C : Implements I, J : " & vbLf & "Sub Goo : End Sub : " & vbLf & "Sub JGoo Implements J.Goo : End Sub : End Class"
- Dim src2 = "Class C : Implements I, J : " & vbLf & "Sub Goo Implements I.Goo : End Sub : " & vbLf & "Sub JGoo Implements J.Goo : End Sub : End Class"
+ Dim src1 = "
+Class C
+ Implements I, J
+
+ Sub Goo
+ End Sub
+
+ Sub JGoo Implements J.Goo
+ End Sub
+End Class
+
+Interface I
+ Sub Goo
+End Interface
+
+Interface J
+ Sub Goo
+End Interface
+"
+ Dim src2 = "
+Class C
+ Implements I, J
+
+ Sub Goo Implements I.Goo
+ End Sub
+
+ Sub JGoo Implements J.Goo
+ End Sub
+End Class
+
+Interface I
+ Sub Goo
+End Interface
+
+Interface J
+ Sub Goo
+End Interface
+"
+
Dim edits = GetTopEdits(src1, src2)
edits.VerifyEdits(
- "Update [Sub Goo]@29 -> [Sub Goo Implements I.Goo]@29")
+ "Update [Sub Goo]@39 -> [Sub Goo Implements I.Goo]@39")
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.ImplementsClauseUpdate, "Sub Goo", FeaturesResources.method))
@@ -3919,16 +4008,53 @@ End Class
Public Sub MethodUpdate_ImplementsUpdate()
- Dim src1 = "Class C : Implements I, J : " & vbLf & "Sub IGoo Implements I.Goo : End Sub : " & vbLf & "Sub JGoo Implements J.Goo : End Sub : End Class"
- Dim src2 = "Class C : Implements I, J : " & vbLf & "Sub IGoo Implements J.Goo : End Sub : " & vbLf & "Sub JGoo Implements I.Goo : End Sub : End Class"
+ Dim src1 = "
+Class C
+ Implements I, J
+
+ Sub Goo Implements I.Goo
+ End Sub
+
+ Sub JGoo Implements J.Goo
+ End Sub
+End Class
+
+Interface I
+ Sub Goo
+End Interface
+
+Interface J
+ Sub Goo
+End Interface
+"
+ Dim src2 = "
+Class C
+ Implements I, J
+
+ Sub Goo Implements J.Goo
+ End Sub
+
+ Sub JGoo Implements I.Goo
+ End Sub
+End Class
+
+Interface I
+ Sub Goo
+End Interface
+
+Interface J
+ Sub Goo
+End Interface
+"
+
Dim edits = GetTopEdits(src1, src2)
edits.VerifyEdits(
- "Update [Sub IGoo Implements I.Goo]@29 -> [Sub IGoo Implements J.Goo]@29",
- "Update [Sub JGoo Implements J.Goo]@68 -> [Sub JGoo Implements I.Goo]@68")
+ "Update [Sub Goo Implements I.Goo]@39 -> [Sub Goo Implements J.Goo]@39",
+ "Update [Sub JGoo Implements J.Goo]@84 -> [Sub JGoo Implements I.Goo]@84")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ImplementsClauseUpdate, "Sub IGoo", FeaturesResources.method),
+ Diagnostic(RudeEditKind.ImplementsClauseUpdate, "Sub Goo", FeaturesResources.method),
Diagnostic(RudeEditKind.ImplementsClauseUpdate, "Sub JGoo", FeaturesResources.method))
End Sub
@@ -4538,7 +4664,7 @@ End Class
"[Public Sub New(a As Integer) : End Sub]@14")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericTypeUpdate, "Public Sub New(a As Integer)", FeaturesResources.constructor))
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Public Sub New(a As Integer)"))
End Sub
@@ -7582,7 +7708,8 @@ End Class
Dim edits = GetTopEdits(src1, src2)
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericTypeInitializerUpdate, "a As Integer = 2", FeaturesResources.field))
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "a As Integer = 2"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Class C(Of T)"))
End Sub
@@ -7592,7 +7719,8 @@ End Class
Dim edits = GetTopEdits(src1, src2)
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericTypeInitializerUpdate, "Property a", FeaturesResources.auto_property))
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Property a"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "Class C(Of T)"))
End Sub
@@ -8023,7 +8151,7 @@ End Class
Dim edits = GetTopEdits(src1, src2)
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Update, "x = 1", FeaturesResources.const_field))
+ Diagnostic(RudeEditKind.InitializerUpdate, "x = 1", FeaturesResources.const_field))
End Sub
@@ -9576,7 +9704,6 @@ End Class
"Insert [A]@27")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, " ", FeaturesResources.method),
Diagnostic(RudeEditKind.Insert, "A", FeaturesResources.type_parameter))
End Sub
@@ -9606,7 +9733,8 @@ End Class
"Delete [A]@27")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Delete, "Public Sub M()", DeletedSymbolDisplay(FeaturesResources.type_parameter, "A")))
+ Diagnostic(RudeEditKind.Delete, "Public Sub M()", DeletedSymbolDisplay(FeaturesResources.type_parameter, "A")),
+ Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, " : ", FeaturesResources.method))
End Sub
@@ -9634,7 +9762,8 @@ End Class
"Update [A]@27 -> [B]@27")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Renamed, "B", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.Renamed, "B", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "B"))
End Sub
@@ -9662,7 +9791,8 @@ End Class
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.Move, "B", FeaturesResources.type_parameter),
- Diagnostic(RudeEditKind.Renamed, "C", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.Renamed, "C", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericMethodUpdate, "C"))
End Sub
#End Region
@@ -9734,7 +9864,8 @@ End Class
"Update [A]@11 -> [B]@11")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Renamed, "B", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.Renamed, "B", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "B"))
End Sub
@@ -9762,7 +9893,8 @@ End Class
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.Move, "B", FeaturesResources.type_parameter),
- Diagnostic(RudeEditKind.Renamed, "C", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.Renamed, "C", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "C"))
End Sub
#End Region
@@ -9778,7 +9910,8 @@ End Class
"Update [T]@11 -> [T As Class]@11")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"))
End Sub
@@ -9791,7 +9924,8 @@ End Class
"Update [S]@11 -> [S As New]@11")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"))
End Sub
@@ -9804,7 +9938,8 @@ End Class
"Update [T As Class]@14 -> [T]@14")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"))
End Sub
@@ -9818,7 +9953,8 @@ End Class
"Update [S As New]@11 -> [S]@11")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"))
End Sub
@@ -9833,7 +9969,9 @@ End Class
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter),
- Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"),
+ Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"))
End Sub
@@ -9848,7 +9986,9 @@ End Class
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter),
- Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"),
+ Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"))
End Sub
@@ -9862,7 +10002,10 @@ End Class
"Update [T As Class]@21 -> [T As {Class}]@23",
"Update [U As I]@33 -> [U As {I}]@37")
- edits.VerifyRudeDiagnostics()
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "T"),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "U"))
End Sub
@@ -9875,7 +10018,8 @@ End Class
"Update [S As {I, J}]@11 -> [S As {J, I}]@11")
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter))
+ Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter),
+ Diagnostic(RudeEditKind.GenericTypeUpdate, "S"))
End Sub
#End Region
diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
index 362af78ee0b3a..79fedf833dda5 100644
--- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
+++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
@@ -186,6 +186,27 @@ protected override ImmutableArray GetCapturedVariables(SemanticModel mo
return model.AnalyzeDataFlow(memberBody).Captured;
}
+ protected override bool AreFixedSizeBufferSizesEqual(IFieldSymbol oldField, IFieldSymbol newField, CancellationToken cancellationToken)
+ {
+ // TODO: replace with symbolic API once available (https://github.com/dotnet/roslyn/issues/54799)
+
+ Debug.Assert(oldField.IsFixedSizeBuffer);
+ Debug.Assert(oldField.DeclaringSyntaxReferences.Length == 1);
+ Debug.Assert(newField.IsFixedSizeBuffer);
+ Debug.Assert(newField.DeclaringSyntaxReferences.Length == 1);
+
+ var oldSyntax = (VariableDeclaratorSyntax)oldField.DeclaringSyntaxReferences.Single().GetSyntax(cancellationToken);
+ var newSyntax = (VariableDeclaratorSyntax)newField.DeclaringSyntaxReferences.Single().GetSyntax(cancellationToken);
+
+ Debug.Assert(oldSyntax.ArgumentList != null);
+ Debug.Assert(newSyntax.ArgumentList != null);
+
+ return AreEquivalent(oldSyntax.ArgumentList, newSyntax.ArgumentList);
+ }
+
+ protected override bool AreHandledEventsEqual(IMethodSymbol oldMethod, IMethodSymbol newMethod)
+ => true;
+
internal override bool HasParameterClosureScope(ISymbol member)
{
// in instance constructor parameters are lifted to a closure different from method body
@@ -1372,6 +1393,7 @@ join newVariable in newVariables on oldVariable.Identifier.Text equals newVariab
var symbol = model.GetDeclaredSymbol(node, cancellationToken);
+ // TODO: this is incorrect (https://github.com/dotnet/roslyn/issues/54800)
// Ignore partial method definition parts.
// Partial method that does not have implementation part is not emitted to metadata.
// Partial method without a definition part is a compilation error.
@@ -1880,6 +1902,7 @@ internal override string GetDisplayName(IMethodSymbol symbol)
{
// top-level
+ case SyntaxKind.CompilationUnit:
case SyntaxKind.GlobalStatement:
return CSharpFeaturesResources.global_statement;
@@ -2238,8 +2261,6 @@ public void ClassifyEdit()
}
}
- #region Move and Reorder
-
private void ClassifyMove(SyntaxNode newNode)
{
if (newNode.IsKind(SyntaxKind.LocalFunctionStatement))
@@ -2261,38 +2282,6 @@ private void ClassifyReorder(SyntaxNode newNode)
switch (newNode.Kind())
{
- case SyntaxKind.GlobalStatement:
- return;
-
- case SyntaxKind.ExternAliasDirective:
- case SyntaxKind.UsingDirective:
- case SyntaxKind.NamespaceDeclaration:
- case SyntaxKind.ClassDeclaration:
- case SyntaxKind.StructDeclaration:
- case SyntaxKind.InterfaceDeclaration:
- case SyntaxKind.RecordDeclaration:
- case SyntaxKind.RecordStructDeclaration:
- case SyntaxKind.EnumDeclaration:
- case SyntaxKind.DelegateDeclaration:
- case SyntaxKind.VariableDeclaration:
- case SyntaxKind.MethodDeclaration:
- case SyntaxKind.ConversionOperatorDeclaration:
- case SyntaxKind.OperatorDeclaration:
- case SyntaxKind.ConstructorDeclaration:
- case SyntaxKind.DestructorDeclaration:
- case SyntaxKind.IndexerDeclaration:
- case SyntaxKind.EventDeclaration:
- case SyntaxKind.GetAccessorDeclaration:
- case SyntaxKind.SetAccessorDeclaration:
- case SyntaxKind.InitAccessorDeclaration:
- case SyntaxKind.AddAccessorDeclaration:
- case SyntaxKind.RemoveAccessorDeclaration:
- case SyntaxKind.TypeParameterConstraintClause:
- case SyntaxKind.AttributeList:
- case SyntaxKind.Attribute:
- // We'll ignore these edits. A general policy is to ignore edits that are only discoverable via reflection.
- return;
-
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.FieldDeclaration:
case SyntaxKind.EventFieldDeclaration:
@@ -2311,38 +2300,19 @@ private void ClassifyReorder(SyntaxNode newNode)
case SyntaxKind.Parameter:
ReportError(RudeEditKind.Move);
return;
-
- default:
- throw ExceptionUtilities.UnexpectedValue(newNode.Kind());
}
}
- #endregion
-
- #region Insert
-
private void ClassifyInsert(SyntaxNode node)
{
switch (node.Kind())
{
- case SyntaxKind.GlobalStatement:
- // An insert of a global statement is actually an update to the synthesized main so we need to check some extra things
- ClassifyUpdate((GlobalStatementSyntax)node);
- return;
-
case SyntaxKind.ExternAliasDirective:
case SyntaxKind.NamespaceDeclaration:
+ case SyntaxKind.FileScopedNamespaceDeclaration:
ReportError(RudeEditKind.Insert);
return;
- case SyntaxKind.ArrowExpressionClause:
- if (node.Parent.IsKind(SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration))
- {
- return;
- }
-
- break;
-
case SyntaxKind.Attribute:
case SyntaxKind.AttributeList:
// To allow inserting of attributes we need to check if the inserted attribute
@@ -2359,33 +2329,18 @@ private void ClassifyInsert(SyntaxNode node)
}
}
- #endregion
-
- #region Delete
-
private void ClassifyDelete(SyntaxNode oldNode)
{
switch (oldNode.Kind())
{
- case SyntaxKind.GlobalStatement:
- return;
-
case SyntaxKind.ExternAliasDirective:
case SyntaxKind.NamespaceDeclaration:
+ case SyntaxKind.FileScopedNamespaceDeclaration:
// To allow removal of declarations we would need to update method bodies that
// were previously binding to them but now are binding to another symbol that was previously hidden.
ReportError(RudeEditKind.Delete);
return;
- case SyntaxKind.ArrowExpressionClause:
- // We do not report error here since it will be reported in semantic analysis.
- if (oldNode.Parent.IsKind(SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration))
- {
- return;
- }
-
- break;
-
case SyntaxKind.AttributeList:
case SyntaxKind.Attribute:
// To allow removal of attributes we need to check if the removed attribute
@@ -2402,18 +2357,10 @@ private void ClassifyDelete(SyntaxNode oldNode)
}
}
- #endregion
-
- #region Update
-
private void ClassifyUpdate(SyntaxNode oldNode, SyntaxNode newNode)
{
switch (newNode.Kind())
{
- case SyntaxKind.GlobalStatement:
- ClassifyUpdate((GlobalStatementSyntax)newNode);
- return;
-
case SyntaxKind.ExternAliasDirective:
ReportError(RudeEditKind.Update);
return;
@@ -2423,58 +2370,6 @@ private void ClassifyUpdate(SyntaxNode oldNode, SyntaxNode newNode)
ClassifyUpdate((BaseNamespaceDeclarationSyntax)oldNode, (BaseNamespaceDeclarationSyntax)newNode);
return;
- case SyntaxKind.VariableDeclaration:
- if (!oldNode.IsParentKind(SyntaxKind.FieldDeclaration, SyntaxKind.EventFieldDeclaration))
- {
- ClassifyUpdate((VariableDeclarationSyntax)oldNode, (VariableDeclarationSyntax)newNode);
- }
-
- return;
-
- case SyntaxKind.VariableDeclarator:
- ClassifyUpdate((VariableDeclaratorSyntax)oldNode, (VariableDeclaratorSyntax)newNode);
- return;
-
- case SyntaxKind.MethodDeclaration:
- ClassifyUpdate((MethodDeclarationSyntax)oldNode, (MethodDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.ConversionOperatorDeclaration:
- ClassifyUpdate((ConversionOperatorDeclarationSyntax)oldNode, (ConversionOperatorDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.OperatorDeclaration:
- ClassifyUpdate((OperatorDeclarationSyntax)oldNode, (OperatorDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.ConstructorDeclaration:
- ClassifyUpdate((ConstructorDeclarationSyntax)oldNode, (ConstructorDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.DestructorDeclaration:
- ClassifyUpdate((DestructorDeclarationSyntax)oldNode, (DestructorDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.PropertyDeclaration:
- ClassifyUpdate((PropertyDeclarationSyntax)oldNode, (PropertyDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.IndexerDeclaration:
- ClassifyUpdate((IndexerDeclarationSyntax)oldNode, (IndexerDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.EnumMemberDeclaration:
- ClassifyUpdate((EnumMemberDeclarationSyntax)oldNode, (EnumMemberDeclarationSyntax)newNode);
- return;
-
- case SyntaxKind.GetAccessorDeclaration:
- case SyntaxKind.SetAccessorDeclaration:
- case SyntaxKind.InitAccessorDeclaration:
- case SyntaxKind.AddAccessorDeclaration:
- case SyntaxKind.RemoveAccessorDeclaration:
- ClassifyUpdate((AccessorDeclarationSyntax)oldNode, (AccessorDeclarationSyntax)newNode);
- return;
-
case SyntaxKind.Attribute:
// To allow update of attributes we need to check if the updated attribute
// is a pseudo-custom attribute that CLR allows us to change, or if it is a compiler well-know attribute
@@ -2490,230 +2385,12 @@ private void ClassifyUpdate(SyntaxNode oldNode, SyntaxNode newNode)
}
}
- private void ClassifyUpdate(GlobalStatementSyntax node)
- {
- ClassifyDeclarationBodyRudeUpdates(node.Statement);
- }
-
private void ClassifyUpdate(BaseNamespaceDeclarationSyntax oldNode, BaseNamespaceDeclarationSyntax newNode)
{
Debug.Assert(!SyntaxFactory.AreEquivalent(oldNode.Name, newNode.Name));
ReportError(RudeEditKind.Renamed);
}
- private void ClassifyUpdate(VariableDeclarationSyntax oldNode, VariableDeclarationSyntax newNode)
- {
- if (!SyntaxFactory.AreEquivalent(oldNode.Type, newNode.Type))
- {
- ReportError(RudeEditKind.TypeUpdate);
- return;
- }
- }
-
- private void ClassifyUpdate(VariableDeclaratorSyntax oldNode, VariableDeclaratorSyntax newNode)
- {
- // If the argument lists are mismatched the field must have mismatched "fixed" modifier,
- // which is reported by the field declaration.
- if (oldNode.ArgumentList is null == newNode.ArgumentList is null)
- {
- if (!SyntaxFactory.AreEquivalent(oldNode.ArgumentList, newNode.ArgumentList))
- {
- ReportError(RudeEditKind.FixedSizeFieldUpdate);
- return;
- }
- }
-
- var typeDeclaration = (TypeDeclarationSyntax?)oldNode.Parent!.Parent!.Parent!;
- if (typeDeclaration.Arity > 0)
- {
- ReportError(RudeEditKind.GenericTypeInitializerUpdate);
- return;
- }
-
- // Check if a constant field is updated:
- var fieldDeclaration = (BaseFieldDeclarationSyntax)oldNode.Parent.Parent;
- if (fieldDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword))
- {
- ReportError(RudeEditKind.Update);
- return;
- }
-
- ClassifyDeclarationBodyRudeUpdates(newNode);
- }
-
- private void ClassifyUpdate(MethodDeclarationSyntax oldNode, MethodDeclarationSyntax newNode)
- {
- ClassifyMethodBodyRudeUpdate(
- (SyntaxNode?)oldNode.Body ?? oldNode.ExpressionBody?.Expression,
- (SyntaxNode?)newNode.Body ?? newNode.ExpressionBody?.Expression,
- containingMethod: newNode,
- containingType: (TypeDeclarationSyntax?)newNode.Parent);
- }
-
- private void ClassifyUpdate(ConversionOperatorDeclarationSyntax oldNode, ConversionOperatorDeclarationSyntax newNode)
- {
- ClassifyMethodBodyRudeUpdate(
- (SyntaxNode?)oldNode.Body ?? oldNode.ExpressionBody?.Expression,
- (SyntaxNode?)newNode.Body ?? newNode.ExpressionBody?.Expression,
- containingMethod: null,
- containingType: (TypeDeclarationSyntax?)newNode.Parent);
- }
-
- private void ClassifyUpdate(OperatorDeclarationSyntax oldNode, OperatorDeclarationSyntax newNode)
- {
- ClassifyMethodBodyRudeUpdate(
- (SyntaxNode?)oldNode.Body ?? oldNode.ExpressionBody?.Expression,
- (SyntaxNode?)newNode.Body ?? newNode.ExpressionBody?.Expression,
- containingMethod: null,
- containingType: (TypeDeclarationSyntax?)newNode.Parent);
- }
-
- private void ClassifyUpdate(AccessorDeclarationSyntax oldNode, AccessorDeclarationSyntax newNode)
- {
- if (oldNode.Kind() != newNode.Kind())
- {
- return;
- }
-
- RoslynDebug.Assert(newNode.Parent is AccessorListSyntax);
- RoslynDebug.Assert(newNode.Parent.Parent is BasePropertyDeclarationSyntax);
-
- ClassifyMethodBodyRudeUpdate(
- (SyntaxNode?)oldNode.Body ?? oldNode.ExpressionBody?.Expression,
- (SyntaxNode?)newNode.Body ?? newNode.ExpressionBody?.Expression,
- containingMethod: null,
- containingType: (TypeDeclarationSyntax?)newNode.Parent.Parent.Parent);
- }
-
- private void ClassifyUpdate(EnumMemberDeclarationSyntax oldNode, EnumMemberDeclarationSyntax newNode)
- {
- if (!SyntaxFactory.AreEquivalent(oldNode.EqualsValue, newNode.EqualsValue))
- {
- ReportError(RudeEditKind.InitializerUpdate);
- return;
- }
-
- // Attributes are processed during semantic analysis
- }
-
- private void ClassifyUpdate(ConstructorDeclarationSyntax oldNode, ConstructorDeclarationSyntax newNode)
- {
- ClassifyMethodBodyRudeUpdate(
- (SyntaxNode?)oldNode.Body ?? oldNode.ExpressionBody?.Expression,
- (SyntaxNode?)newNode.Body ?? newNode.ExpressionBody?.Expression,
- containingMethod: null,
- containingType: (TypeDeclarationSyntax?)newNode.Parent);
- }
-
- private void ClassifyUpdate(DestructorDeclarationSyntax oldNode, DestructorDeclarationSyntax newNode)
- {
- ClassifyMethodBodyRudeUpdate(
- (SyntaxNode?)oldNode.Body ?? oldNode.ExpressionBody?.Expression,
- (SyntaxNode?)newNode.Body ?? newNode.ExpressionBody?.Expression,
- containingMethod: null,
- containingType: (TypeDeclarationSyntax?)newNode.Parent);
- }
-
- private void ClassifyUpdate(PropertyDeclarationSyntax oldNode, PropertyDeclarationSyntax newNode)
- {
- var containingType = (TypeDeclarationSyntax)newNode.Parent!;
-
- // TODO: We currently don't support switching from auto-props to properties with accessors and vice versa.
- // If we do we should also allow it for expression bodies.
-
- if (!SyntaxFactory.AreEquivalent(oldNode.ExpressionBody, newNode.ExpressionBody))
- {
- var oldBody = SyntaxUtilities.TryGetEffectiveGetterBody(oldNode.ExpressionBody, oldNode.AccessorList);
- var newBody = SyntaxUtilities.TryGetEffectiveGetterBody(newNode.ExpressionBody, newNode.AccessorList);
-
- ClassifyMethodBodyRudeUpdate(
- oldBody,
- newBody,
- containingMethod: null,
- containingType: containingType);
-
- return;
- }
-
- if (!SyntaxFactory.AreEquivalent(oldNode.Initializer, newNode.Initializer))
- {
- if (containingType.Arity > 0)
- {
- ReportError(RudeEditKind.GenericTypeInitializerUpdate);
- return;
- }
-
- if (newNode.Initializer != null)
- {
- ClassifyDeclarationBodyRudeUpdates(newNode.Initializer);
- }
- }
- }
-
- private void ClassifyUpdate(IndexerDeclarationSyntax oldNode, IndexerDeclarationSyntax newNode)
- {
- if (SyntaxFactory.AreEquivalent(oldNode.ExpressionBody, newNode.ExpressionBody))
- {
- var oldBody = SyntaxUtilities.TryGetEffectiveGetterBody(oldNode.ExpressionBody, oldNode.AccessorList);
- var newBody = SyntaxUtilities.TryGetEffectiveGetterBody(newNode.ExpressionBody, newNode.AccessorList);
-
- ClassifyMethodBodyRudeUpdate(
- oldBody,
- newBody,
- containingMethod: null,
- containingType: (TypeDeclarationSyntax?)newNode.Parent);
- }
- }
-
- private void ClassifyMethodBodyRudeUpdate(
- SyntaxNode? oldBody,
- SyntaxNode? newBody,
- MethodDeclarationSyntax? containingMethod,
- TypeDeclarationSyntax? containingType)
- {
- Debug.Assert(oldBody is BlockSyntax || oldBody is ExpressionSyntax || oldBody == null);
- Debug.Assert(newBody is BlockSyntax || newBody is ExpressionSyntax || newBody == null);
-
- if ((oldBody == null) != (newBody == null))
- {
- if (oldBody == null)
- {
- ReportError(RudeEditKind.MethodBodyAdd);
- return;
- }
- else
- {
- ReportError(RudeEditKind.MethodBodyDelete);
- return;
- }
- }
-
- ClassifyMemberBodyRudeUpdate(containingMethod, containingType, isTriviaUpdate: false);
-
- if (newBody != null)
- {
- ClassifyDeclarationBodyRudeUpdates(newBody);
- }
- }
-
- public void ClassifyMemberBodyRudeUpdate(
- MethodDeclarationSyntax? containingMethod,
- TypeDeclarationSyntax? containingType,
- bool isTriviaUpdate)
- {
- if (SyntaxUtilities.Any(containingMethod?.TypeParameterList))
- {
- ReportError(isTriviaUpdate ? RudeEditKind.GenericMethodTriviaUpdate : RudeEditKind.GenericMethodUpdate);
- return;
- }
-
- if (SyntaxUtilities.Any(containingType?.TypeParameterList))
- {
- ReportError(isTriviaUpdate ? RudeEditKind.GenericTypeTriviaUpdate : RudeEditKind.GenericTypeUpdate);
- return;
- }
- }
-
public void ClassifyDeclarationBodyRudeUpdates(SyntaxNode newDeclarationOrBody)
{
foreach (var node in newDeclarationOrBody.DescendantNodesAndSelf(LambdaUtilities.IsNotLambda))
@@ -2727,8 +2404,6 @@ public void ClassifyDeclarationBodyRudeUpdates(SyntaxNode newDeclarationOrBody)
}
}
}
-
- #endregion
}
internal override void ReportTopLevelSyntacticRudeEdits(
@@ -2746,15 +2421,9 @@ internal override void ReportTopLevelSyntacticRudeEdits(
classifier.ClassifyEdit();
}
- internal override void ReportMemberUpdateRudeEdits(ArrayBuilder diagnostics, SyntaxNode newMember, TextSpan? span)
+ internal override void ReportMemberBodyUpdateRudeEdits(ArrayBuilder diagnostics, SyntaxNode newMember, TextSpan? span)
{
var classifier = new EditClassifier(this, diagnostics, oldNode: null, newMember, EditKind.Update, span: span);
-
- classifier.ClassifyMemberBodyRudeUpdate(
- newMember as MethodDeclarationSyntax,
- newMember.FirstAncestorOrSelf(),
- isTriviaUpdate: true);
-
classifier.ClassifyDeclarationBodyRudeUpdates(newMember);
}
diff --git a/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs b/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
index 8fe1d00a96ea2..176a52ebd9c13 100644
--- a/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
+++ b/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
@@ -287,6 +287,9 @@ protected virtual bool StateMachineSuspensionPointKindEquals(SyntaxNode suspensi
///
protected abstract IEnumerable GetVariableUseSites(IEnumerable roots, ISymbol localOrParameter, SemanticModel model, CancellationToken cancellationToken);
+ protected abstract bool AreFixedSizeBufferSizesEqual(IFieldSymbol oldField, IFieldSymbol newField, CancellationToken cancellationToken);
+ protected abstract bool AreHandledEventsEqual(IMethodSymbol oldMethod, IMethodSymbol newMethod);
+
// diagnostic spans:
protected abstract TextSpan? TryGetDiagnosticSpan(SyntaxNode node, EditKind editKind);
@@ -400,7 +403,7 @@ protected virtual string GetSuspensionPointDisplayName(SyntaxNode node, EditKind
internal abstract void ReportTopLevelSyntacticRudeEdits(ArrayBuilder diagnostics, Match match, Edit edit, Dictionary editMap);
internal abstract void ReportEnclosingExceptionHandlingRudeEdits(ArrayBuilder diagnostics, IEnumerable> exceptionHandlingEdits, SyntaxNode oldStatement, TextSpan newStatementSpan);
internal abstract void ReportOtherRudeEditsAroundActiveStatement(ArrayBuilder diagnostics, Match match, SyntaxNode oldStatement, SyntaxNode newStatement, bool isNonLeaf);
- internal abstract void ReportMemberUpdateRudeEdits(ArrayBuilder diagnostics, SyntaxNode newMember, TextSpan? span);
+ internal abstract void ReportMemberBodyUpdateRudeEdits(ArrayBuilder diagnostics, SyntaxNode newMember, TextSpan? span);
internal abstract void ReportInsertedMemberSymbolRudeEdits(ArrayBuilder diagnostics, ISymbol newSymbol, SyntaxNode newNode, bool insertingIntoExistingContainingType);
internal abstract void ReportStateMachineSuspensionPointRudeEdits(ArrayBuilder diagnostics, SyntaxNode oldNode, SyntaxNode newNode);
@@ -604,30 +607,17 @@ public async Task AnalyzeDocumentAsync(
cancellationToken.ThrowIfCancellationRequested();
- using var _3 = ArrayBuilder<(SyntaxNode OldNode, SyntaxNode NewNode)>.GetInstance(out var triviaEdits);
+ using var _3 = ArrayBuilder<(SyntaxNode OldNode, SyntaxNode NewNode, TextSpan DiagnosticSpan)>.GetInstance(out var triviaEdits);
using var _4 = ArrayBuilder.GetInstance(out var lineEdits);
- // Do not analyze trivia in presence of syntactic rude edits.
- // The implementation depends on edit map capturing all updates and inserts,
- // which might not be the case when rude edits are reported.
- if (diagnostics.Count == 0)
- {
- AnalyzeTrivia(
- topMatch,
- editMap,
- triviaEdits,
- lineEdits,
- diagnostics,
- cancellationToken);
-
- if (diagnostics.Count > 0 && !hasRudeEdits)
- {
- DocumentAnalysisResults.Log.Write("{0} trivia rude edits, first: {1}@{2}", diagnostics.Count, newDocument.FilePath, diagnostics.First().Span.Start);
- hasRudeEdits = true;
- }
+ AnalyzeTrivia(
+ topMatch,
+ editMap,
+ triviaEdits,
+ lineEdits,
+ cancellationToken);
- cancellationToken.ThrowIfCancellationRequested();
- }
+ cancellationToken.ThrowIfCancellationRequested();
var oldActiveStatements = (oldTree == null) ? ImmutableArray.Empty :
oldActiveStatementMap.GetOldActiveStatements(this, oldTree, oldText, oldRoot, cancellationToken);
@@ -705,11 +695,6 @@ private void ReportTopLevelSyntacticRudeEdits(ArrayBuilder d
///
internal virtual void ReportDeclarationInsertDeleteRudeEdits(ArrayBuilder diagnostics, SyntaxNode oldNode, SyntaxNode newNode, ISymbol oldSymbol, ISymbol newSymbol, CancellationToken cancellationToken)
{
- if (oldSymbol is ITypeParameterSymbol or IParameterSymbol)
- {
- return;
- }
-
// When a method is moved to a different declaration and its parameters are changed at the same time
// the new method symbol key will not resolve to the old one since the parameters are different.
// As a result we will report separate delete and insert rude edits.
@@ -723,25 +708,7 @@ internal virtual void ReportDeclarationInsertDeleteRudeEdits(ArrayBuilder BuildEditMap(EditScript editScript)
@@ -974,6 +941,8 @@ private void AnalyzeChangedMemberBody(
try
{
+ ReportMemberBodyUpdateRudeEdits(diagnostics, newDeclaration, GetDiagnosticSpan(newDeclaration, EditKind.Update));
+
_testFaultInjector?.Invoke(newBody);
// Populated with active lambdas and matched lambdas.
@@ -2036,13 +2005,10 @@ private static int IndexOfEquivalent(SyntaxNode newNode, List topMatch,
IReadOnlyDictionary editMap,
- [Out] ArrayBuilder<(SyntaxNode OldNode, SyntaxNode NewNode)> triviaEdits,
+ [Out] ArrayBuilder<(SyntaxNode OldNode, SyntaxNode NewNode, TextSpan DiagnosticSpan)> triviaEdits,
[Out] ArrayBuilder lineEdits,
- [Out] ArrayBuilder diagnostics,
CancellationToken cancellationToken)
{
- Debug.Assert(diagnostics.Count == 0);
-
var oldTree = topMatch.OldRoot.SyntaxTree;
var newTree = topMatch.NewRoot.SyntaxTree;
@@ -2211,8 +2177,6 @@ void AddCurrentSegment()
// All tokens of a member body have been processed now.
if (requiresUpdate)
{
- triviaEdits.Add((oldNode, newNode));
-
// report the rude edit for the span of tokens that forced recompilation:
if (rudeEditSpan.IsEmpty)
{
@@ -2221,7 +2185,7 @@ void AddCurrentSegment()
newTokensEnum.Current.SpanStart);
}
- ReportMemberUpdateRudeEdits(diagnostics, newNode, rudeEditSpan);
+ triviaEdits.Add((oldNode, newNode, rudeEditSpan));
// remove all segments added for the current member body:
segments.Count = firstSegmentIndex;
@@ -2274,8 +2238,7 @@ void AddCurrentSegment()
{
// The segment overlaps the previous one that has a different line delta. We need to recompile the method.
// The debugger filters out line deltas that correspond to recompiled methods so we don't need to.
- triviaEdits.Add((segment.oldNode, segment.newNode));
- ReportMemberUpdateRudeEdits(diagnostics, segment.newNode, span: null);
+ triviaEdits.Add((segment.oldNode, segment.newNode, segment.newNode.Span));
continue;
}
@@ -2358,6 +2321,9 @@ public int GetHashCode(IAssemblySymbol? obj)
private static readonly SymbolEquivalenceComparer s_exactSymbolEqualityComparer = new(
AssemblyEqualityComparer.Instance, distinguishRefFromOut: true, tupleNamesMustMatch: true, ignoreNullableAnnotations: false);
+ protected static bool SymbolsEquivalent(ISymbol oldSymbol, ISymbol newSymbol)
+ => s_exactSymbolEqualityComparer.Equals(oldSymbol, newSymbol);
+
protected static bool SignaturesEquivalent(ImmutableArray oldParameters, ITypeSymbol oldReturnType, ImmutableArray newParameters, ITypeSymbol newReturnType)
=> ParametersEquivalent(oldParameters, newParameters, exact: false) &&
s_runtimeSymbolEqualityComparer.Equals(oldReturnType, newReturnType); // TODO: should check ref, ref readonly, custom mods
@@ -2369,18 +2335,21 @@ protected static bool CustomModifiersEquivalent(CustomModifier oldModifier, Cust
=> oldModifier.IsOptional == newModifier.IsOptional &&
TypesEquivalent(oldModifier.Modifier, newModifier.Modifier, exact);
+ protected static bool CustomModifiersEquivalent(ImmutableArray oldModifiers, ImmutableArray newModifiers, bool exact)
+ => oldModifiers.SequenceEqual(newModifiers, exact, (x, y, exact) => CustomModifiersEquivalent(x, y, exact));
+
protected static bool ReturnTypesEquivalent(IMethodSymbol oldMethod, IMethodSymbol newMethod, bool exact)
=> oldMethod.ReturnsByRef == newMethod.ReturnsByRef &&
oldMethod.ReturnsByRefReadonly == newMethod.ReturnsByRefReadonly &&
- oldMethod.ReturnTypeCustomModifiers.SequenceEqual(newMethod.ReturnTypeCustomModifiers, exact, (x, y, exact) => CustomModifiersEquivalent(x, y, exact)) &&
- oldMethod.RefCustomModifiers.SequenceEqual(newMethod.RefCustomModifiers, exact, (x, y, exact) => CustomModifiersEquivalent(x, y, exact)) &&
+ CustomModifiersEquivalent(oldMethod.ReturnTypeCustomModifiers, newMethod.ReturnTypeCustomModifiers, exact) &&
+ CustomModifiersEquivalent(oldMethod.RefCustomModifiers, newMethod.RefCustomModifiers, exact) &&
TypesEquivalent(oldMethod.ReturnType, newMethod.ReturnType, exact);
protected static bool ReturnTypesEquivalent(IPropertySymbol oldProperty, IPropertySymbol newProperty, bool exact)
=> oldProperty.ReturnsByRef == newProperty.ReturnsByRef &&
oldProperty.ReturnsByRefReadonly == newProperty.ReturnsByRefReadonly &&
- oldProperty.TypeCustomModifiers.SequenceEqual(newProperty.TypeCustomModifiers, exact, (x, y, exact) => CustomModifiersEquivalent(x, y, exact)) &&
- oldProperty.RefCustomModifiers.SequenceEqual(newProperty.RefCustomModifiers, exact, (x, y, exact) => CustomModifiersEquivalent(x, y, exact)) &&
+ CustomModifiersEquivalent(oldProperty.TypeCustomModifiers, newProperty.TypeCustomModifiers, exact) &&
+ CustomModifiersEquivalent(oldProperty.RefCustomModifiers, newProperty.RefCustomModifiers, exact) &&
TypesEquivalent(oldProperty.Type, newProperty.Type, exact);
protected static bool ReturnTypesEquivalent(IEventSymbol oldEvent, IEventSymbol newEvent, bool exact)
@@ -2390,11 +2359,14 @@ protected static bool ReturnTypesEquivalent(IEventSymbol oldEvent, IEventSymbol
protected static bool TypesEquivalent(ITypeSymbol? oldType, ITypeSymbol? newType, bool exact)
=> (exact ? s_exactSymbolEqualityComparer : (IEqualityComparer)s_runtimeSymbolEqualityComparer.SignatureTypeEquivalenceComparer).Equals(oldType, newType);
+ protected static bool TypesEquivalent(ImmutableArray oldTypes, ImmutableArray newTypes, bool exact) where T : ITypeSymbol
+ => oldTypes.SequenceEqual(newTypes, exact, (x, y, exact) => TypesEquivalent(x, y, exact));
+
protected static bool ParameterTypesEquivalent(IParameterSymbol oldParameter, IParameterSymbol newParameter, bool exact)
=> (exact ? s_exactSymbolEqualityComparer : s_runtimeSymbolEqualityComparer).ParameterEquivalenceComparer.Equals(oldParameter, newParameter);
protected static bool TypeParameterConstraintsEquivalent(ITypeParameterSymbol oldParameter, ITypeParameterSymbol newParameter, bool exact)
- => oldParameter.ConstraintTypes.SequenceEqual(newParameter.ConstraintTypes, exact, (x, y, exact) => TypesEquivalent(x, y, exact)) &&
+ => TypesEquivalent(oldParameter.ConstraintTypes, newParameter.ConstraintTypes, exact) &&
oldParameter.HasReferenceTypeConstraint == newParameter.HasReferenceTypeConstraint &&
oldParameter.HasValueTypeConstraint == newParameter.HasValueTypeConstraint &&
oldParameter.HasConstructorConstraint == newParameter.HasConstructorConstraint &&
@@ -2407,7 +2379,7 @@ protected static bool TypeParametersEquivalent(ImmutableArray TypesEquivalent(oldType.BaseType, newType.BaseType, exact) &&
- oldType.AllInterfaces.SequenceEqual(newType.AllInterfaces, exact, (x, y, exact) => TypesEquivalent(x, y, exact));
+ TypesEquivalent(oldType.AllInterfaces, newType.AllInterfaces, exact);
protected static bool MemberSignaturesEquivalent(
ISymbol? oldMember,
@@ -2470,7 +2442,7 @@ private async Task> AnalyzeSemanticsAsync(
IReadOnlyDictionary editMap,
ImmutableArray oldActiveStatements,
ImmutableArray newActiveStatementSpans,
- IReadOnlyList<(SyntaxNode OldNode, SyntaxNode NewNode)> triviaEdits,
+ IReadOnlyList<(SyntaxNode OldNode, SyntaxNode NewNode, TextSpan DiagnosticSpan)> triviaEdits,
Project oldProject,
Document? oldDocument,
Document newDocument,
@@ -2553,19 +2525,14 @@ private async Task> AnalyzeSemanticsAsync(
// Treat the edit as Insert/Delete. This may happen e.g. when all C# global statements are removed, the first one is added or they are moved to another file.
if (syntacticEditKind == EditKind.Update)
{
- if (oldSymbol == null)
+ if (oldSymbol == null || oldDeclaration != null && oldDeclaration.SyntaxTree != oldModel?.SyntaxTree)
{
syntacticEditKind = EditKind.Insert;
}
- else if (newSymbol == null)
+ else if (newSymbol == null || newDeclaration != null && newDeclaration.SyntaxTree != newModel.SyntaxTree)
{
syntacticEditKind = EditKind.Delete;
}
- else if (oldDeclaration != null && oldModel != null && oldDeclaration.SyntaxTree != oldModel.SyntaxTree ||
- newDeclaration != null && newDeclaration.SyntaxTree != newModel.SyntaxTree)
- {
- syntacticEditKind = edit.Kind;
- }
}
switch (syntacticEditKind)
@@ -3035,24 +3002,7 @@ private async Task> AnalyzeSemanticsAsync(
Contract.ThrowIfNull(oldSymbol);
AnalyzeSymbolUpdate(oldSymbol, newSymbol, edit.NewNode, newCompilation, capabilities, diagnostics, semanticEdits, syntaxMap, cancellationToken);
-
- // The only update to the type itself that's supported is an addition or removal of the partial modifier,
- // which does not have impact on the emitted type metadata.
- if (newSymbol is INamedTypeSymbol)
- {
- continue;
- }
-
- // The field/property/event itself is being updated. Currently we do not allow any modifiers to be updated.
- // Attribute updates will have been handled already.
- if (newSymbol is IFieldSymbol or IPropertySymbol or IEventSymbol)
- {
- continue;
- }
-
- // The only updates allowed for a parameter or type parameter is an attribute change, but we only need the edit
- // for the containing symbol which will be handled elsewhere.
- if (newSymbol is IParameterSymbol or ITypeParameterSymbol)
+ if (newSymbol is INamedTypeSymbol or IFieldSymbol or IPropertySymbol or IEventSymbol or IParameterSymbol or ITypeParameterSymbol)
{
continue;
}
@@ -3064,7 +3014,7 @@ private async Task> AnalyzeSemanticsAsync(
}
}
- foreach (var (oldEditNode, newEditNode) in triviaEdits)
+ foreach (var (oldEditNode, newEditNode, diagnosticSpan) in triviaEdits)
{
Contract.ThrowIfNull(oldModel);
Contract.ThrowIfNull(newModel);
@@ -3120,6 +3070,16 @@ private async Task> AnalyzeSemanticsAsync(
continue;
}
+ ReportMemberBodyUpdateRudeEdits(diagnostics, newDeclaration, diagnosticSpan);
+
+ // updating generic methods and types
+ if (InGenericContext(oldSymbol, out var oldIsGenericMethod))
+ {
+ var rudeEdit = oldIsGenericMethod ? RudeEditKind.GenericMethodTriviaUpdate : RudeEditKind.GenericTypeTriviaUpdate;
+ diagnostics.Add(new RudeEditDiagnostic(rudeEdit, diagnosticSpan, newEditNode, new[] { GetDisplayName(newEditNode) }));
+ continue;
+ }
+
// Edits in data member initializers and constructors are deferred, edits of other members (even on partial types)
// do not need merging accross partial type declarations.
var symbolKey = SymbolKey.Create(newSymbol, cancellationToken);
@@ -3247,7 +3207,8 @@ private void ReportUpdatedSymbolDeclarationRudeEdits(
if (oldSymbol.IsStatic != newSymbol.IsStatic ||
oldSymbol.IsVirtual != newSymbol.IsVirtual ||
oldSymbol.IsAbstract != newSymbol.IsAbstract ||
- oldSymbol.IsOverride != newSymbol.IsOverride)
+ oldSymbol.IsOverride != newSymbol.IsOverride ||
+ oldSymbol.IsExtern != newSymbol.IsExtern)
{
// Do not report for accessors as the error will be reported on their associated symbol.
if (oldSymbol is not IMethodSymbol { AssociatedSymbol: not null })
@@ -3265,6 +3226,21 @@ private void ReportUpdatedSymbolDeclarationRudeEdits(
rudeEdit = RudeEditKind.ModifiersUpdate;
}
+ // Report rude edit for updating const fields and values of enums.
+ // The latter is only reported whne the enum underlying type does not change to avoid cascading rude edits.
+ if (oldField.IsConst && newField.IsConst && !Equals(oldField.ConstantValue, newField.ConstantValue) &&
+ TypesEquivalent(oldField.ContainingType.EnumUnderlyingType, newField.ContainingType.EnumUnderlyingType, exact: false))
+ {
+ rudeEdit = RudeEditKind.InitializerUpdate;
+ }
+
+ if (oldField.IsFixedSizeBuffer &&
+ newField.IsFixedSizeBuffer &&
+ !AreFixedSizeBufferSizesEqual(oldField, newField, cancellationToken))
+ {
+ rudeEdit = RudeEditKind.FixedSizeFieldUpdate;
+ }
+
AnalyzeType(oldField.Type, newField.Type, ref rudeEdit, ref hasGeneratedAttributeChange);
}
else if (oldSymbol is IMethodSymbol oldMethod && newSymbol is IMethodSymbol newMethod)
@@ -3312,6 +3288,18 @@ private void ReportUpdatedSymbolDeclarationRudeEdits(
}
}
+ // VB implements clause
+ if (!oldMethod.ExplicitInterfaceImplementations.SequenceEqual(newMethod.ExplicitInterfaceImplementations, (x, y) => SymbolsEquivalent(x, y)))
+ {
+ rudeEdit = RudeEditKind.ImplementsClauseUpdate;
+ }
+
+ // VB handles clause
+ if (!AreHandledEventsEqual(oldMethod, newMethod))
+ {
+ rudeEdit = RudeEditKind.HandlesClauseUpdate;
+ }
+
// Check return type - do not report for accessors, their containing symbol will report the rude edits and attribute updates.
if (rudeEdit == RudeEditKind.None && oldMethod.AssociatedSymbol == null && newMethod.AssociatedSymbol == null)
{
@@ -3550,6 +3538,13 @@ private void AnalyzeSymbolUpdate(
{
AddCustomAttributeSemanticEdits(semanticEdits, newSymbol, syntaxMap, hasAttributeChange, hasReturnTypeAttributeChange, cancellationToken);
}
+
+ // updating generic methods and types
+ if (InGenericContext(oldSymbol, out var oldIsGenericMethod) || InGenericContext(newSymbol, out _))
+ {
+ var rudeEdit = oldIsGenericMethod ? RudeEditKind.GenericMethodUpdate : RudeEditKind.GenericTypeUpdate;
+ ReportUpdateRudeEdit(diagnostics, rudeEdit, newSymbol, newNode, cancellationToken);
+ }
}
private static void AddCustomAttributeSemanticEdits(
@@ -3874,7 +3869,12 @@ private void ReportUpdateRudeEdit(ArrayBuilder diagnostics,
{
var node = newNode ?? GetRudeEditDiagnosticNode(newSymbol, cancellationToken);
var span = (rudeEdit == RudeEditKind.ChangeImplicitMainReturnType) ? GetGlobalStatementDiagnosticSpan(node) : GetDiagnosticSpan(node, EditKind.Update);
- var arguments = (rudeEdit is RudeEditKind.TypeKindUpdate or RudeEditKind.ChangeImplicitMainReturnType) ? Array.Empty() : new[] { GetDisplayName(newSymbol) };
+
+ var arguments = (rudeEdit is
+ RudeEditKind.TypeKindUpdate or
+ RudeEditKind.ChangeImplicitMainReturnType or
+ RudeEditKind.GenericMethodUpdate or
+ RudeEditKind.GenericTypeUpdate) ? Array.Empty() : new[] { GetDisplayName(newSymbol) };
diagnostics.Add(new RudeEditDiagnostic(rudeEdit, span, node, arguments));
}
@@ -4236,7 +4236,7 @@ static bool IsNotInDocument(SyntaxReference reference, SyntaxTree syntaxTree)
(accumulate, node) => (node.SpanStart < accumulate.min) ? (node.SpanStart, node.Span) : accumulate).span;
Contract.ThrowIfTrue(firstSpan.IsEmpty);
- ReportMemberUpdateRudeEdits(diagnostics, newDeclaration, firstSpan);
+ ReportMemberBodyUpdateRudeEdits(diagnostics, newDeclaration, firstSpan);
}
// When explicitly implementing the copy constructor of a record the parameter name must match for symbol matching to work
@@ -4251,9 +4251,8 @@ static bool IsNotInDocument(SyntaxReference reference, SyntaxTree syntaxTree)
diagnostics.Add(new RudeEditDiagnostic(
RudeEditKind.ExplicitRecordMethodParameterNamesMustMatch,
GetDiagnosticSpan(newDeclaration, EditKind.Update),
- arguments: new[] {
- oldCtor.ToDisplayString(SymbolDisplayFormats.NameFormat)
- }));
+ arguments: new[] { oldCtor.ToDisplayString(SymbolDisplayFormats.NameFormat) }));
+
continue;
}
}
@@ -5226,7 +5225,7 @@ private void ReportStateMachineRudeEdits(
#endregion
- #region Helpers
+ #region Helpers
private static SyntaxNode? TryGetNode(SyntaxNode root, int position)
=> root.FullSpan.Contains(position) ? root.FindToken(position).Parent : null;
@@ -5287,6 +5286,33 @@ private static bool IsGlobalMain(ISymbol symbol)
=> symbol is IMethodSymbol { Name: WellKnownMemberNames.TopLevelStatementsEntryPointMethodName, ContainingType.Name: WellKnownMemberNames.TopLevelStatementsEntryPointTypeName };
#pragma warning restore format
+ private static bool InGenericContext(ISymbol symbol, out bool isGenericMethod)
+ {
+ var current = symbol;
+
+ while (true)
+ {
+ if (current is IMethodSymbol { Arity: > 0 })
+ {
+ isGenericMethod = true;
+ return true;
+ }
+
+ if (current is INamedTypeSymbol { Arity: > 0 })
+ {
+ isGenericMethod = false;
+ return true;
+ }
+
+ current = current.ContainingSymbol;
+ if (current == null)
+ {
+ isGenericMethod = false;
+ return false;
+ }
+ }
+ }
+
#endregion
#region Testing
@@ -5323,17 +5349,6 @@ internal Match ComputeBodyMatch(
{
return _abstractEditAndContinueAnalyzer.ComputeBodyMatch(oldBody, newBody, activeNodes, diagnostics, out oldHasStateMachineSuspensionPoint, out newHasStateMachineSuspensionPoint);
}
-
- internal void AnalyzeTrivia(
- Match topMatch,
- IReadOnlyDictionary editMap,
- [Out] ArrayBuilder<(SyntaxNode OldNode, SyntaxNode NewNode)> triviaEdits,
- [Out] ArrayBuilder lineEdits,
- [Out] ArrayBuilder diagnostics,
- CancellationToken cancellationToken)
- {
- _abstractEditAndContinueAnalyzer.AnalyzeTrivia(topMatch, editMap, triviaEdits, lineEdits, diagnostics, cancellationToken);
- }
}
#endregion
diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs
index bbc3e647a839d..edf44e821eef1 100644
--- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs
+++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs
@@ -96,8 +96,6 @@ void AddGeneralDiagnostic(EditAndContinueErrorCode code, string resourceName, Di
AddRudeEdit(RudeEditKind.InsertGenericMethod, nameof(FeaturesResources.Adding_a_generic_0_will_prevent_the_debug_session_from_continuing));
AddRudeEdit(RudeEditKind.Move, nameof(FeaturesResources.Moving_0_will_prevent_the_debug_session_from_continuing));
AddRudeEdit(RudeEditKind.Delete, nameof(FeaturesResources.Deleting_0_will_prevent_the_debug_session_from_continuing));
- AddRudeEdit(RudeEditKind.MethodBodyAdd, nameof(FeaturesResources.Adding_a_method_body_will_prevent_the_debug_session_from_continuing));
- AddRudeEdit(RudeEditKind.MethodBodyDelete, nameof(FeaturesResources.Deleting_a_method_body_will_prevent_the_debug_session_from_continuing));
AddRudeEdit(RudeEditKind.GenericMethodUpdate, nameof(FeaturesResources.Modifying_a_generic_method_will_prevent_the_debug_session_from_continuing));
AddRudeEdit(RudeEditKind.GenericMethodTriviaUpdate, nameof(FeaturesResources.Modifying_whitespace_or_comments_in_a_generic_0_will_prevent_the_debug_session_from_continuing));
AddRudeEdit(RudeEditKind.GenericTypeUpdate, nameof(FeaturesResources.Modifying_a_method_inside_the_context_of_a_generic_type_will_prevent_the_debug_session_from_continuing));
diff --git a/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs b/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs
index 6a641e23d4379..a976f5eb8e78a 100644
--- a/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs
+++ b/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs
@@ -47,8 +47,8 @@ internal enum RudeEditKind : ushort
InsertIntoClassWithLayout = 31,
Move = 32,
Delete = 33,
- MethodBodyAdd = 34,
- MethodBodyDelete = 35,
+ // MethodBodyAdd = 34,
+ // MethodBodyDelete = 35,
GenericMethodUpdate = 36,
GenericMethodTriviaUpdate = 37,
GenericTypeUpdate = 38,
diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx
index 97bd53da30702..73ee20ce8e880 100644
--- a/src/Features/Core/Portable/FeaturesResources.resx
+++ b/src/Features/Core/Portable/FeaturesResources.resx
@@ -507,12 +507,6 @@
Deleting '{0}' around an active statement will prevent the debug session from continuing.
-
- Adding a method body will prevent the debug session from continuing.
-
-
- Deleting a method body will prevent the debug session from continuing.
-
An active statement has been removed from its original method. You must revert your changes to continue or restart the debugging session.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf
index 7d0d239fdc2d9..cc356be6ece44 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf
@@ -3304,16 +3304,6 @@ Pokud se specifikátor formátu g použije bez dalších specifikátorů vlastn
Odstranění prvku {0} v okolí aktivního příkazu zabrání v pokračování relace ladění.
-
-
- Přidání těla metody zabrání v pokračování relace ladění.
-
-
-
-
- Odstranění těla metody zabrání v pokračování relace ladění.
-
-
Aktualizace modifikátoru async nebo iterator kolem aktivního příkazu bude bránit relaci ladění v tom, aby pokračovala.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf
index 339902abb3b37..be3144797f9e3 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf
@@ -3304,16 +3304,6 @@ Bei Verwendung des Formatbezeichners "g" ohne weitere benutzerdefinierte Formatb
Durch Löschen von "{0}" um eine aktive Anweisung herum wird verhindert, dass die Debuggingsitzung fortgesetzt wird.
-
-
- Durch Hinzufügen eines Methodenkörpers wird verhindert, dass die Debuggingsitzung fortgesetzt wird.
-
-
-
-
- Durch Löschen eines Methodenkörpers wird verhindert, dass eine Debuggingsitzung fortgesetzt wird.
-
-
Eine asynchrone Aktualisierung oder ein iteratormodifizierer um eine aktive Anweisung verhindert, dass die Debugsitzung fortgesetzt wird.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf
index bdc894f0c2e1a..eaa1749cb69f4 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf
@@ -3304,16 +3304,6 @@ Si el especificador de formato "g" se usa sin otros especificadores de formato p
Eliminar '{0}' en una instrucción activa impedirá que continúe la sesión de depuración.
-
-
- Agregar un cuerpo de método impedirá que continúe la sesión de depuración.
-
-
-
-
- Eliminar un cuerpo de método impedirá que continúe la sesión de depuración.
-
-
La actualización del modificador async o iterator en una instrucción activa impedirá que la sesión de depuración continúe.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf
index f92ccdedc18bf..3129470c0141e 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf
@@ -3304,16 +3304,6 @@ Si le spécificateur de format "g" est utilisé sans autres spécificateurs de f
La suppression de '{0}' autour d'une instruction active empêche la session de débogage de se poursuivre.
-
-
- L'ajout d'un corps de méthode empêche la session de débogage de se poursuivre.
-
-
-
-
- La suppression d'un corps de méthode empêche la session de débogage de se poursuivre.
-
-
La mise à jour d'un modificateur async ou iterator autour d'une instruction active empêche la session de débogage de se poursuivre.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf
index 9d13a938e5066..819457a5f11b1 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf
@@ -3304,16 +3304,6 @@ Se l'identificatore di formato "g" viene usato senza altri identificatori di for
Se si elimina '{0}' in prossimità di un'istruzione attiva, la sessione di debug non potrà continuare.
-
-
- Se si aggiunge un corpo del metodo, la sessione di debug non potrà continuare.
-
-
-
-
- Se si elimina un corpo del metodo, la sessione di debug non potrà continuare.
-
-
Se si aggiorna un modificatore iterator o async in prossimità di un'istruzione attiva, la sessione di debug non potrà continuare.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf
index 66d41c2fd01fe..16381ccc5f2c9 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf
@@ -3304,16 +3304,6 @@ If the "g" format specifier is used without other custom format specifiers, it's
アクティブ ステートメントの前後の '{0}' を削除すると、デバッグ セッションは続行されません。
-
-
- メソッド本体を追加すると、デバッグ セッションは続行されません。
-
-
-
-
- メソッド本体を削除すると、デバッグ セッションは続行されません。
-
-
アクティブ ステートメントの前後の async 修飾子または iterator 修飾子を更新すると、デバッグ セッションが継続しなくなります。
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf
index 4a5730dd76c44..1a5b762cd534d 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf
@@ -3304,16 +3304,6 @@ If the "g" format specifier is used without other custom format specifiers, it's
활성 문 주위에서 '{0}'을(를) 삭제하면 디버그 세션을 계속할 수 없습니다.
-
-
- 메서드 본문을 추가하면 디버그 세션을 계속할 수 없습니다.
-
-
-
-
- 메서드 본문을 삭제하면 디버그 세션을 계속할 수 없습니다.
-
-
활성 문 주위의 async 또는 iterator 한정자를 업데이트하면 디버그 세션이 계속되지 않습니다.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf
index 66f37d7e2207f..9a1aebfd64925 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf
@@ -3304,16 +3304,6 @@ Jeśli specyfikator formatu „g” jest używany bez innych niestandardowych sp
Usunięcie elementu „{0}” w ramach aktywnej instrukcji uniemożliwi kontynuowanie sesji debugowania.
-
-
- Dodanie treści metody uniemożliwi kontynuowanie sesji debugowania.
-
-
-
-
- Usunięcie treści metody uniemożliwi kontynuowanie sesji debugowania.
-
-
Aktualizowanie modyfikatora asynchronicznego lub powiązanego z iteratorem w pobliżu aktywnej instrukcji uniemożliwi kontynuowanie sesji debugowania.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf
index abb54b4699b88..055c7b78a3e82 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf
@@ -3304,16 +3304,6 @@ Se o especificador de formato "g" for usado sem outros especificadores de format
Excluir "{0}" em uma instrução ativa impedirá que a sessão de depuração continue.
-
-
- Adicionar um corpo do método impedirá que a sessão de depuração continue.
-
-
-
-
- Excluir um corpo de método impedirá que a sessão de depuração continue.
-
-
A atualização do modificador "async" ou "iterator" em torno de uma instrução ativa impedirá a sessão de depuração de continuar.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf
index 11e679e57d815..cdb668ea6c403 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf
@@ -3304,16 +3304,6 @@ If the "g" format specifier is used without other custom format specifiers, it's
Удаление "{0}" рядом с активным оператором сделает продолжение сеанса отладки невозможным.
-
-
- Добавление тела метода сделает продолжение сеанса отладки невозможным.
-
-
-
-
- Удаление тела метода сделает продолжение сеанса отладки невозможным.
-
-
Обновление модификатора async или iterator рядом с активным оператором сделает продолжение сеанса отладки невозможным.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf
index f640b1efd5fb7..dfc553f36d4db 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf
@@ -3304,16 +3304,6 @@ If the "g" format specifier is used without other custom format specifiers, it's
Etkin bir deyimin etrafından '{0}' öğesini silme, hata ayıklama oturumunun devam etmesini engelleyecek.
-
-
- Bir yöntem gövdesi ekleme, hata ayıklama oturumunun devam etmesini engelleyecek.
-
-
-
-
- Bir yöntem gövdesi silme, hata ayıklama oturumunun devam etmesini engelleyecek.
-
-
Etkin bir deyimin etrafındaki async ya da iterator değiştiricisini güncelleştirmek hata ayıklama oturumunun devam etmesini önler.
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf
index eeb8e3f0073fe..8d5a4962c373a 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf
@@ -3304,16 +3304,6 @@ If the "g" format specifier is used without other custom format specifiers, it's
删除活动语句周围的“{0}”将阻止调试会话继续。
-
-
- 添加方法主体将阻止调试会话继续。
-
-
-
-
- 删除方法主体将阻止调试会话继续。
-
-
更新当前语句的 async 或 iterator 修饰符可以阻止调试会话继续。
diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf
index 7bfbd66b92237..2e434493caf66 100644
--- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf
+++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf
@@ -3304,16 +3304,6 @@ If the "g" format specifier is used without other custom format specifiers, it's
刪除現用陳述式前後的 '{0}',會造成偵錯工作階段無法繼續。
-
-
- 加入方法主體,會造成偵錯工作階段無法繼續。
-
-
-
-
- 刪除方法主體,會造成偵錯工作階段無法繼續。
-
-
更新作用中陳述式前後的 async 或 iterator 修飾元,會造成偵錯工作階段無法繼續。
diff --git a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
index 48c816486ac67..bd5083287b434 100644
--- a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
+++ b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
@@ -2289,52 +2289,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
ClassifyUpdate(DirectCast(oldNode, NamespaceStatementSyntax), DirectCast(newNode, NamespaceStatementSyntax))
Return
- Case SyntaxKind.VariableDeclarator
- ClassifyUpdate(DirectCast(oldNode, VariableDeclaratorSyntax), DirectCast(newNode, VariableDeclaratorSyntax))
- Return
-
- Case SyntaxKind.ModifiedIdentifier
- ClassifyUpdate(DirectCast(newNode, ModifiedIdentifierSyntax))
- Return
-
- Case SyntaxKind.SubBlock,
- SyntaxKind.FunctionBlock
- ClassifyUpdate(DirectCast(oldNode, MethodBlockSyntax), DirectCast(newNode, MethodBlockSyntax))
- Return
-
- Case SyntaxKind.SubStatement,
- SyntaxKind.FunctionStatement
- ClassifyUpdate(DirectCast(oldNode, MethodStatementSyntax), DirectCast(newNode, MethodStatementSyntax))
- Return
-
- Case SyntaxKind.OperatorBlock
- ClassifyUpdate(DirectCast(oldNode, OperatorBlockSyntax), DirectCast(newNode, OperatorBlockSyntax))
- Return
-
- Case SyntaxKind.ConstructorBlock
- ClassifyUpdate(DirectCast(oldNode, ConstructorBlockSyntax), DirectCast(newNode, ConstructorBlockSyntax))
- Return
-
- Case SyntaxKind.PropertyStatement
- ClassifyUpdate(DirectCast(oldNode, PropertyStatementSyntax), DirectCast(newNode, PropertyStatementSyntax))
- Return
-
- Case SyntaxKind.EventStatement
- ClassifyUpdate(DirectCast(oldNode, EventStatementSyntax), DirectCast(newNode, EventStatementSyntax))
- Return
-
- Case SyntaxKind.GetAccessorBlock,
- SyntaxKind.SetAccessorBlock,
- SyntaxKind.AddHandlerAccessorBlock,
- SyntaxKind.RemoveHandlerAccessorBlock,
- SyntaxKind.RaiseEventAccessorBlock
- ClassifyUpdate(DirectCast(oldNode, AccessorBlockSyntax), DirectCast(newNode, AccessorBlockSyntax))
- Return
-
- Case SyntaxKind.EnumMemberDeclaration
- ClassifyUpdate(DirectCast(oldNode, EnumMemberDeclarationSyntax), DirectCast(newNode, EnumMemberDeclarationSyntax))
- Return
-
Case SyntaxKind.AttributesStatement
ReportError(RudeEditKind.Update)
Return
@@ -2354,161 +2308,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
ReportError(RudeEditKind.Renamed)
End Sub
- Private Sub ClassifyUpdate(newNode As ModifiedIdentifierSyntax)
- ' Otherwise only the size of the array changed, which is a legal initializer update
- ' unless it contains lambdas, queries etc.
- ClassifyDeclarationBodyRudeUpdates(newNode)
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As VariableDeclaratorSyntax, newNode As VariableDeclaratorSyntax)
- Dim typeDeclaration = DirectCast(oldNode.Parent.Parent, TypeBlockSyntax)
- If typeDeclaration.BlockStatement.Arity > 0 Then
- ReportError(RudeEditKind.GenericTypeInitializerUpdate)
- Return
- End If
-
- If ClassifyTypeAndInitializerUpdates(oldNode.Initializer,
- oldNode.AsClause,
- newNode.Initializer,
- newNode.AsClause) Then
- ' Check if a constant field is updated:
- Dim fieldDeclaration = DirectCast(oldNode.Parent, FieldDeclarationSyntax)
- If fieldDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword) Then
- ReportError(RudeEditKind.Update)
- Return
- End If
- End If
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As PropertyStatementSyntax, newNode As PropertyStatementSyntax)
- If Not SyntaxFactory.AreEquivalent(oldNode.ImplementsClause, newNode.ImplementsClause) Then
- ReportError(RudeEditKind.ImplementsClauseUpdate)
- Return
- End If
-
- If ClassifyTypeAndInitializerUpdates(oldNode.Initializer, oldNode.AsClause, newNode.Initializer, newNode.AsClause) Then
- ' change in an initializer of an auto-property
- Dim typeDeclaration = DirectCast(oldNode.Parent, TypeBlockSyntax)
- If typeDeclaration.BlockStatement.Arity > 0 Then
- ReportError(RudeEditKind.GenericTypeInitializerUpdate)
- Return
- End If
- End If
- End Sub
-
- ' Returns true if the initializer has changed.
- Private Function ClassifyTypeAndInitializerUpdates(oldEqualsValue As EqualsValueSyntax,
- oldClause As AsClauseSyntax,
- newEqualsValue As EqualsValueSyntax,
- newClause As AsClauseSyntax) As Boolean
-
- Dim oldInitializer = GetInitializerExpression(oldEqualsValue, oldClause)
- Dim newInitializer = GetInitializerExpression(newEqualsValue, newClause)
-
- If newInitializer IsNot Nothing AndAlso Not SyntaxFactory.AreEquivalent(oldInitializer, newInitializer) Then
- ClassifyDeclarationBodyRudeUpdates(newInitializer)
- Return True
- End If
-
- Return False
- End Function
-
- Private Sub ClassifyUpdate(oldNode As EventStatementSyntax, newNode As EventStatementSyntax)
- ' A custom event can't be matched with a field event and vice versa:
- Debug.Assert(SyntaxFactory.AreEquivalent(oldNode.CustomKeyword, newNode.CustomKeyword))
-
- If Not SyntaxFactory.AreEquivalent(oldNode.ImplementsClause, newNode.ImplementsClause) Then
- ReportError(RudeEditKind.ImplementsClauseUpdate)
- Return
- End If
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As MethodBlockSyntax, newNode As MethodBlockSyntax)
- ClassifyMethodBodyRudeUpdate(oldNode,
- newNode,
- containingMethod:=newNode,
- containingType:=DirectCast(newNode.Parent, TypeBlockSyntax))
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As MethodStatementSyntax, newNode As MethodStatementSyntax)
- ' TODO (tomat): We can support this
- If Not SyntaxFactory.AreEquivalent(oldNode.HandlesClause, newNode.HandlesClause) Then
- ReportError(RudeEditKind.HandlesClauseUpdate)
- Return
- End If
-
- If Not SyntaxFactory.AreEquivalent(oldNode.ImplementsClause, newNode.ImplementsClause) Then
- ReportError(RudeEditKind.ImplementsClauseUpdate)
- Return
- End If
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As OperatorBlockSyntax, newNode As OperatorBlockSyntax)
- ClassifyMethodBodyRudeUpdate(oldNode,
- newNode,
- containingMethod:=Nothing,
- containingType:=DirectCast(newNode.Parent, TypeBlockSyntax))
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As AccessorBlockSyntax, newNode As AccessorBlockSyntax)
- Debug.Assert(newNode.Parent.IsKind(SyntaxKind.EventBlock) OrElse
- newNode.Parent.IsKind(SyntaxKind.PropertyBlock))
-
- ClassifyMethodBodyRudeUpdate(oldNode,
- newNode,
- containingMethod:=Nothing,
- containingType:=DirectCast(newNode.Parent.Parent, TypeBlockSyntax))
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As EnumMemberDeclarationSyntax, newNode As EnumMemberDeclarationSyntax)
- If Not SyntaxFactory.AreEquivalent(oldNode.Initializer, newNode.Initializer) Then
- ReportError(RudeEditKind.InitializerUpdate)
- Return
- End If
- End Sub
-
- Private Sub ClassifyUpdate(oldNode As ConstructorBlockSyntax, newNode As ConstructorBlockSyntax)
- ClassifyMethodBodyRudeUpdate(oldNode,
- newNode,
- containingMethod:=Nothing,
- containingType:=DirectCast(newNode.Parent, TypeBlockSyntax))
- End Sub
-
- Private Sub ClassifyMethodBodyRudeUpdate(oldBody As MethodBlockBaseSyntax,
- newBody As MethodBlockBaseSyntax,
- containingMethod As MethodBlockSyntax,
- containingType As TypeBlockSyntax)
-
- If (oldBody.EndBlockStatement Is Nothing) <> (newBody.EndBlockStatement Is Nothing) Then
- If oldBody.EndBlockStatement Is Nothing Then
- ReportError(RudeEditKind.MethodBodyAdd)
- Return
- Else
- ReportError(RudeEditKind.MethodBodyDelete)
- Return
- End If
- End If
-
- ' The method only gets called if there are no other changes to the method declaration.
- ' Since we got the update edit something has to be different in the body.
- Debug.Assert(newBody.EndBlockStatement IsNot Nothing)
-
- ClassifyMemberBodyRudeUpdate(containingMethod, containingType, isTriviaUpdate:=False)
- ClassifyDeclarationBodyRudeUpdates(newBody)
- End Sub
-
- Public Sub ClassifyMemberBodyRudeUpdate(containingMethodOpt As MethodBlockSyntax, containingTypeOpt As TypeBlockSyntax, isTriviaUpdate As Boolean)
- If containingMethodOpt?.SubOrFunctionStatement.TypeParameterList IsNot Nothing Then
- ReportError(If(isTriviaUpdate, RudeEditKind.GenericMethodTriviaUpdate, RudeEditKind.GenericMethodUpdate))
- Return
- End If
-
- If containingTypeOpt?.BlockStatement.Arity > 0 Then
- ReportError(If(isTriviaUpdate, RudeEditKind.GenericTypeTriviaUpdate, RudeEditKind.GenericTypeUpdate))
- Return
- End If
- End Sub
-
Public Sub ClassifyDeclarationBodyRudeUpdates(newDeclarationOrBody As SyntaxNode)
For Each node In newDeclarationOrBody.DescendantNodesAndSelf()
Select Case node.Kind
@@ -2565,20 +2364,29 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
classifier.ClassifyEdit()
End Sub
- Friend Overrides Sub ReportMemberUpdateRudeEdits(diagnostics As ArrayBuilder(Of RudeEditDiagnostic), newMember As SyntaxNode, span As TextSpan?)
+ Friend Overrides Sub ReportMemberBodyUpdateRudeEdits(diagnostics As ArrayBuilder(Of RudeEditDiagnostic), newMember As SyntaxNode, span As TextSpan?)
Dim classifier = New EditClassifier(Me, diagnostics, Nothing, newMember, EditKind.Update, span:=span)
-
- classifier.ClassifyMemberBodyRudeUpdate(
- TryCast(newMember, MethodBlockSyntax),
- newMember.FirstAncestorOrSelf(Of TypeBlockSyntax)(),
- isTriviaUpdate:=True)
-
classifier.ClassifyDeclarationBodyRudeUpdates(newMember)
End Sub
#End Region
#Region "Semantic Rude Edits"
+ Protected Overrides Function AreFixedSizeBufferSizesEqual(oldField As IFieldSymbol, newField As IFieldSymbol, cancellationToken As CancellationToken) As Boolean
+ Throw ExceptionUtilities.Unreachable
+ End Function
+
+ Protected Overrides Function AreHandledEventsEqual(oldMethod As IMethodSymbol, newMethod As IMethodSymbol) As Boolean
+ Return oldMethod.HandledEvents.SequenceEqual(
+ newMethod.HandledEvents,
+ Function(x, y)
+ Return x.HandlesKind = y.HandlesKind AndAlso
+ SymbolsEquivalent(x.EventContainer, y.EventContainer) AndAlso
+ SymbolsEquivalent(x.EventSymbol, y.EventSymbol) AndAlso
+ SymbolsEquivalent(x.WithEventsSourceProperty, y.WithEventsSourceProperty)
+ End Function)
+ End Function
+
Friend Overrides Sub ReportInsertedMemberSymbolRudeEdits(diagnostics As ArrayBuilder(Of RudeEditDiagnostic), newSymbol As ISymbol, newNode As SyntaxNode, insertingIntoExistingContainingType As Boolean)
Dim kind = GetInsertedMemberSymbolRudeEditKind(newSymbol, insertingIntoExistingContainingType)