Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

EnC rude edit for local function attributes #49027

Closed
Closed
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6994c91
Add failing tests
davidwengier Oct 29, 2020
92b44bd
Add rude edit kind and string resources
davidwengier Oct 29, 2020
f821ebb
Compare local function attributes
davidwengier Oct 29, 2020
ac100d6
Revert "Add rude edit kind and string resources"
davidwengier Nov 2, 2020
1b34636
Extract to separate method
davidwengier Nov 2, 2020
84350fd
Use Update edit klnd instead of a new one
davidwengier Nov 2, 2020
c20471e
Add rude edits for local function return attributes
davidwengier Nov 2, 2020
1d76be7
Check local function parameter attributes
davidwengier Nov 2, 2020
70306a4
Globalize
davidwengier Nov 4, 2020
7774e96
Move tests and rename
davidwengier Dec 1, 2020
79e3583
Add attribute list tests
davidwengier Dec 1, 2020
7dd36d8
Reword
davidwengier Dec 1, 2020
d3df67d
Change visibility
davidwengier Dec 1, 2020
c864484
Make method abstract so we can switch to syntax
davidwengier Dec 1, 2020
8b8384a
Compare attribute lists for local functions and their parameters
davidwengier Dec 1, 2020
c4448b3
Implement abstract method
davidwengier Dec 1, 2020
7a09aee
Doc and simplify
davidwengier Dec 1, 2020
a21cfe9
Highlight the best changed span for the user.
davidwengier Dec 2, 2020
2e6fdeb
Fix correctness issues
davidwengier Dec 2, 2020
da8c371
Add failing tests for local function type parameter attributes
davidwengier Dec 6, 2020
71fbac0
Flag local function type parameter attribute changes
davidwengier Dec 6, 2020
839e6fa
Cleanup
davidwengier Dec 6, 2020
7de6782
Report better error messages on diagnostics
davidwengier Dec 6, 2020
b3798e5
Add attributes and parameters to the statement comparer
davidwengier Dec 7, 2020
7af49ef
Use statement comparer for local function attribute tests
davidwengier Dec 7, 2020
c89638f
Change assert to if, so map is only updated when necessary
davidwengier Dec 20, 2020
1022a0e
Update statement editing tests for new edits
davidwengier Dec 20, 2020
ef94988
Update statement matching tests for new matched spans
davidwengier Dec 20, 2020
a6002ad
Update error spans test to remove spans that are now labeled
davidwengier Dec 21, 2020
fd14c5a
Add rude edit validation to statement editing tests
davidwengier Jan 14, 2021
c890dca
Remove old syntax analysis code
davidwengier Jan 14, 2021
b4a420b
PR feedback
davidwengier Jan 14, 2021
9e2f0e4
Classify top level edits and statement edits separately where necessary
davidwengier Jan 14, 2021
ebea62b
Report rude edits for method body syntax related to local functions
davidwengier Jan 14, 2021
52dc819
Analyze local functions by their declaraions
davidwengier Jan 24, 2021
792c0de
Allow multiple interesting child nodes to be included for local funct…
davidwengier Jan 29, 2021
8770aed
Wrap arguments
davidwengier Jan 29, 2021
c00dc79
Merge remote-tracking branch 'upstream/master' into EnCLocalFunctionA…
davidwengier Jan 29, 2021
e1acecb
Merge remote-tracking branch 'upstream/master' into EnCLocalFunctionA…
davidwengier Jan 31, 2021
3569e2b
Handle null parameter type in lambda parameters
davidwengier Feb 1, 2021
14838f6
Don't use the top level edit flag in one place
davidwengier Feb 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ void M()
/*<span>*/expr;/*</span>*/
/*<span>*/int a;/*</span>*/
F(/*<span>*/(x)/*</span>*/ => x);
F(/*<span>*/x/*</span>*/ => x);
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
F(/*<span>*/delegate/*</span>*/(x) { });
F(from a in b /*<span>*/select/*</span>*/ a.x);
F(from a in b /*<span>*/let/*</span>*/ x = expr select expr);
Expand Down
204 changes: 195 additions & 9 deletions src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1841,7 +1841,10 @@ public void Lambdas_InVariableDeclarator()

edits.VerifyEdits(
"Update [a => a]@13 -> [(a) => a]@13",
"Update [b => b]@25 -> [b => b + 1]@27");
"Update [b => b]@25 -> [b => b + 1]@27",
"Insert [(a)]@13",
"Insert [a]@14",
"Delete [a]@13");
}

[Fact]
Expand Down Expand Up @@ -1894,7 +1897,7 @@ public void Lambdas_InLambda_ChangeInLambdaSignature()

// changes were made to the outer lambda signature:
edits.VerifyEdits(
"Update [() => { G(x => y); }]@4 -> [q => { G(() => y); }]@4");
"Update [() => { G(x => y); }]@4 -> [q => { G(() => y); }]@4", "Insert [q]@4", "Delete [()]@4");
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
}

[Fact]
Expand All @@ -1918,7 +1921,7 @@ public void Lambdas_Update_ParameterRefness_NoBodyChange()
var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits(
"Update [(ref int a) => a = 1]@4 -> [(out int a) => a = 1]@4");
"Update [ref int a]@5 -> [out int a]@5");
}

[Fact]
Expand Down Expand Up @@ -4745,7 +4748,10 @@ public void LocalFunctions_InExpressionStatement()
edits.VerifyEdits(
"Update [a => a]@4 -> [int x(int a) => a + 1;]@2",
"Move [a => a]@4 -> @2",
"Update [F(a => a, b => b);]@2 -> [F(b => b, x);]@25");
"Update [F(a => a, b => b);]@2 -> [F(b => b, x);]@25",
"Insert [(int a)]@7",
"Insert [int a]@8",
"Delete [a]@4");
}

[Fact]
Expand Down Expand Up @@ -4774,7 +4780,10 @@ public void LocalFunctions_InWhile()
"Update [int x(int a) => a + 1;]@28 -> [a => a]@11",
"Move [int x(int a) => a + 1;]@28 -> @11",
"Move [{ /*1*/ }]@5 -> @20",
"Delete [do { /*1*/ } while (F(x));]@2");
"Insert [a]@11",
"Delete [do { /*1*/ } while (F(x));]@2",
"Delete [(int a)]@33",
"Delete [int a]@34");
}

[Fact]
Expand All @@ -4796,8 +4805,7 @@ public void LocalFunctions_InLocalFunction_ChangeInSignature()

var edits = GetMethodEdits(src1, src2);
// changes were made to the outer local function signature:
edits.VerifyEdits(
"Update [int x() { int y(int a) => a; return y(b); }]@2 -> [int x(int z) { int y() => c; return y(); }]@2");
edits.VerifyEdits("Insert [int z]@8");
}

[Fact]
Expand All @@ -4809,7 +4817,9 @@ public void LocalFunctions_InLambda()
var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits(
"Update [() => { int y(int a) => a; G(y); }]@4 -> [q => { G(() => y); }]@4");
"Update [() => { int y(int a) => a; G(y); }]@4 -> [q => { G(() => y); }]@4",
"Insert [q]@4",
"Delete [()]@4");
}

[Fact]
Expand All @@ -4821,7 +4831,7 @@ public void LocalFunctions_Update_ParameterRefness_NoBodyChange()
var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits(
"Update [void f(ref int a) => a = 1;]@2 -> [void f(out int a) => a = 1;]@2");
"Update [ref int a]@9 -> [out int a]@9");
}

[Fact]
Expand Down Expand Up @@ -6933,6 +6943,182 @@ public void LocalFunction_RemoveAsync()
Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "local", FeaturesResources.local_function));
}

[Fact]
public void LocalFunction_AddAttribute()
{
var src1 = "void L() { }";
var src2 = "[A]void L() { }";

var edits = GetMethodEdits(src1, src2);
davidwengier marked this conversation as resolved.
Show resolved Hide resolved

edits.VerifyEdits("Insert [[A]]@2", "Insert [A]@3");
}

[Fact]
public void LocalFunction_RemoveAttribute()
{
var src1 = "[A]void L() { }";
var src2 = "void L() { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Delete [[A]]@2", "Delete [A]@3");
}

[Fact]
public void LocalFunction_ReorderAttribute()
{
var src1 = "[A, B]void L() { }";
var src2 = "[B, A]void L() { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Reorder [B]@6 -> @3");
}

[Fact]
public void LocalFunction_CombineAttributeLists()
{
var src1 = "[A][B]void L() { }";
var src2 = "[A, B]void L() { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Update [[A]]@2 -> [[A, B]]@2", "Insert [B]@6", "Delete [[B]]@5", "Delete [B]@6");
}

[Fact]
public void LocalFunction_SplitAttributeLists()
{
var src1 = "[A, B]void L() { }";
var src2 = "[A][B]void L() { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Update [[A, B]]@2 -> [[A]]@2", "Insert [[B]]@5", "Insert [B]@6", "Delete [B]@6");
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
}

[Fact]
public void LocalFunction_ChangeAttributeListTarget1()
{
var src1 = "[return: A]void L() { }";
var src2 = "[A]void L() { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Update [[return: A]]@2 -> [[A]]@2");
}

[Fact]
public void LocalFunction_ChangeAttributeListTarget2()
{
var src1 = "[A]void L() { }";
var src2 = "[return: A]void L() { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Update [[A]]@2 -> [[return: A]]@2");
}

[Fact]
public void LocalFunction_ReturnType_AddAttribute()
{
var src1 = "int L() { return 1; }";
var src2 = "[return: A]int L() { return 1; }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Insert [[return: A]]@2", "Insert [A]@11");
}

[Fact]
public void LocalFunction_ReturnType_RemoveAttribute()
{
var src1 = "[return: A]int L() { return 1; }";
var src2 = "int L() { return 1; }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Delete [[return: A]]@2", "Delete [A]@11");
}

[Fact]
public void LocalFunction_ReturnType_ReorderAttribute()
{
var src1 = "[return: A, B]int L() { return 1; }";
var src2 = "[return: B, A]int L() { return 1; }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Reorder [B]@14 -> @11");
}

[Fact]
public void LocalFunction_Parameter_AddAttribute()
{
var src1 = "void L(int i) { }";
var src2 = "void L([A]int i) { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Insert [[A]]@9", "Insert [A]@10");
}

[Fact]
public void LocalFunction_Parameter_RemoveAttribute()
{
var src1 = "void L([A]int i) { }";
var src2 = "void L(int i) { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Delete [[A]]@9", "Delete [A]@10");
}

[Fact]
public void LocalFunction_Parameter_ReorderAttribute()
{
var src1 = "void L([A, B]int i) { }";
var src2 = "void L([B, A]int i) { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Reorder [B]@13 -> @10");
}

[Fact]
public void LocalFunction_TypeParameter_AddAttribute()
{
var src1 = "void L<T>(T i) { }";
var src2 = "void L<[A] T>(T i) { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Insert [[A]]@9", "Insert [A]@10");
}

[Fact]
public void LocalFunction_TypeParameter_RemoveAttribute()
{
var src1 = "void L<[A] T>(T i) { }";
var src2 = "void L<T>(T i) { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Delete [[A]]@9", "Delete [A]@10");
}

[Fact]
public void LocalFunction_TypeParameter_ReorderAttribute()
{
var src1 = "void L<[A, B] T>(T i) { }";
var src2 = "void L<[B, A] T>(T i) { }";

var edits = GetMethodEdits(src1, src2);

edits.VerifyEdits("Reorder [B]@13 -> @10");
}

#endregion

#region Queries
Expand Down
Loading