-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Add helper methods to Verify operation tree for annonated text within… #17856
Conversation
… a source file. These APIs will be used in autogenerated unit test for Operation tree verification.
In general, can you tag me on these? Thanks! |
Tagging @dotnet/roslyn-analysis @dotnet/roslyn-compiler for review. |
@jinujoseph Can you create a new GitHub group for all IOperation folks (4 of us in team and Cyrus and Gen)? |
@dotnet-bot retest ubuntu_14_debug_prtest please |
@dotnet-bot retest windows_release_vs-integration_prtest please |
@dotnet/analyzer-ioperation is the new team name for this. |
👍 |
return null; | ||
} | ||
|
||
var operation = model.GetOperationInternal(syntaxNode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can a node have multiple operations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and we need to test that SemanticModel.GetOperation
does give us the expected bound node, lowest or highest. I see that VB and C# seem to have different defaults. C# picks the lowest bound node when there are multiple bound nodes for a syntax (see here) and VB picks the highest (see here). I will open a separate work item to track why this difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so when testing.. do we want to explicit on IOperation we get from the API? or we use the default behavior?
can user get IOperation off a node? or is it only internal, testing stuff?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a API discussion I believe. SemanticModel.GetOperation doesn't seem to take an options, but we have an internal enum GetOperationOptions that decides what bound node to choose for clashes. Until we expose that publically, unit tests should just use the default that the GetOperation API passes down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed #17861
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so for users, they expect 1 node to have 1 IOperation 1:1 matching?
hmm.. but when they examine SyntaxNode of IOperation, they might get multiple IOperation with same node right? how users get to those IOperations? only through walker?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, seems we need to expose the options when there are conflict - needs design discussion. You can probably add comment to #17861
{ | ||
var tree = compilation.SyntaxTrees[0]; | ||
var model = compilation.GetSemanticModel(tree); | ||
SyntaxNode syntaxNode = GetSyntaxNodeOfTypeForBinding<TSyntaxNode>(GetSyntaxNodeList(tree)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happen if tree has multiple nodes matching given type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will behave similar to the compiler binding tests for those cases. Seems that this method adds the nodes from bottom up, and picks the first node that matches full text and is of expected type. Also I am not sure if we can have 2 nodes of same kind with same span in tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but this test doesn't give in span? so it will just pick the first node in the tree?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unit test generator will add comments denoting the span, like following:
- VB:
Dim x1 = New F()
Dim x2 = New F() With {.Field = 2}'BIND:"Dim x2 = New F() With {.Field = 2}"
Dim x3 = New F() With {.Property1 = ""}
Dim x4 = New F() With {.Property1 = "", .Field = 2}
Dim x5 = New F() With {.Property2 = New B() With {.Field = True}}
- C#
class C
{
public void M1()
/*<bind>*/{
var x1 = new F();
var x2 = new F() { Field = 2 };
var x3 = new F() { Property1 = """""""" };
var x4 = new F() { Property1 = """""""", Field = 2 };
var x5 = new F() { Property2 = new B { Field = true } };
var e1 = new F() { Property2 = 1 };
var e2 = new F() { """""""" };
}/*</bind>*/
}
bind
comments specify the span that the test helper will use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See example unit test: https://github.com/dotnet/roslyn-internal/pull/1692#issuecomment-286570489
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I see, no span argument is needed since it will get those from source, got it.
@@ -151,4 +152,32 @@ Public MustInherit Class SemanticModelTestBase : Inherits BasicTestBase | |||
).Where(Function(s) anyArity OrElse DirectCast(s, Symbol).GetArity() = arity.Value).ToList() | |||
End Function | |||
|
|||
Friend Function GetOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, Optional which As Integer = 0) As String |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting so compiler test framework between VB and C# is different slightly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it seems there are differences between binding test framework helpers, and I had to retain them so I can re-use it.
char[] newLineChars = Environment.NewLine.ToCharArray(); | ||
string actual = actualOperationTree.Trim(newLineChars); | ||
expectedOperationTree = expectedOperationTree.Trim(newLineChars); | ||
expectedOperationTree = Regex.Replace(expectedOperationTree, "([^\r])\n", "$1" + Environment.NewLine); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does it actually trying to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is due to the CDATA for VB. It seems to have \n
characters instead of new lines, and this causes equality check to fail. This line replaces \n
characters, that do not have a \r
before it, with \r\n
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm.. but you trimmed new lines right above, regex so, there will be no \r or \n in text anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will trim just \r\n
from start and end. We need to retain the newline characters within the text so that assert failure displays the actual and expected IOperation tree in a nicely formatted manner in the test window.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. so escaped char is retained but actually "\r\n" will be removed. okay.
{ | ||
public static IOperation GetOperationInternal(this SemanticModel model, SyntaxNode node) | ||
{ | ||
return model.GetOperationInternal(node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what this extension method is trying to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it calling itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is to bypass the feature flag check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetOperationInternal is internal method on semantic model that by-passes the IOperation feature flag check. Only core TestUtilties have IVT, so this just exposes it to other test layers, such as ETA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, got it. some comment would help :) since it looks like it is calling itself ha ha.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sure.
👍 |
@dotnet-bot test windows_debug_unit32_prtest please |
@dotnet test windows_release_vs-integration_prtest please |
windows_release_vs-integration_prtest is failing due to unrelated failure:
|
@dotnet-bot retest ubuntu_14_debug_prtest please |
… a source file.
These APIs will be used in autogenerated unit test for Operation tree verification.