-
Notifications
You must be signed in to change notification settings - Fork 229
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
TokenType: Tests and optimization for pointer types #8060
Changes from all commits
abd754c
0b65a9b
de3fb78
ee876df
5aa01e1
459d68d
0539173
d5f8409
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1329,4 +1329,50 @@ public void M({{parameterDeclaration}}) | |
} | ||
} | ||
""", allowSemanticModel); | ||
|
||
[DataTestMethod] | ||
[DataRow("var d = [u:dateTimePointer]->Date;", false)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Educational: could you please briefly explain when a token is of an unknown type (i.e. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unknown is the default tokentype and is used for all tokens that are not of any of the other types: public enum TokenType {
[pbr::OriginalName("UNKNOWN_TOKENTYPE")] UnknownTokentype = 0,
[pbr::OriginalName("TYPE_NAME")] TypeName = 1,
[pbr::OriginalName("NUMERIC_LITERAL")] NumericLiteral = 2,
[pbr::OriginalName("STRING_LITERAL")] StringLiteral = 3,
[pbr::OriginalName("KEYWORD")] Keyword = 4,
[pbr::OriginalName("COMMENT")] Comment = 5,
} "Unknown" tokens are skipped when the info is written to the disc because there is no difference. |
||
[DataRow("var d = dateTimePointer->[u:Date];", false)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Educational: I guess There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Also: *) One exception is "value" in property setters, which is classified as a keyword. |
||
[DataRow("var d = (*[u:dateTimePointer]).Date;", false)] | ||
[DataRow("var d = (*dateTimePointer).[u:Date];", false)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Educational: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. I try to assert only single tokens as it eases the test debugging. Also, the |
||
[DataRow("var d = [u:dateTimePointer][0];", false)] | ||
[DataRow("[u:dateTimePointer][0] = *(&[u:dateTimePointer][0]);", false)] | ||
[DataRow("[t:Int32]* iPointer;", false)] | ||
[DataRow("[t:Int32]?* iPointer;", false)] | ||
[DataRow("[t:Int32]?** iPointerPointer;", false)] | ||
[DataRow("[t:Nullable]<[t:Int32]>** iPointerPointer;", false)] | ||
[DataRow("[u:System].Int32* iPointer;", true)] | ||
[DataRow("System.[t:Int32]* iPointer;", false)] | ||
[DataRow("[k:void]* voidPointer;", false)] | ||
[DataRow("DateTime d = default; M(&[u:d]);", false)] | ||
[DataRow("[t:DateTime]** dt = &[u:dateTimePointer];", false)] | ||
[DataRow("_ = (*(&[u:dateTimePointer]))->Date;", false)] | ||
[DataRow("_ = (**(&[u:dateTimePointer])).Date;", false)] | ||
public void IdentifierToken_Unsafe_Pointers(string statement, bool allowSemanticModel) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are some additional test cases that come to mind: int?* x1; // Pointer of a nullable value type ("?" shouldn't be part of the token, right?
Nullable<int>* x2; // Nullable is of type t, whereas int is of type k, both are recognized
int** x3; // ** is not included in the token int, which is of type k And relative assignments: _ = &x1; // x1 of type u
_ = (*(&x1))->Value; // x1 and Value of type u
_ = (*x1).Value; // x1 and Value of type u There are also ways of mixing var @int = (int*)null; // 2nd int and null of type k, 1st int of type u (?) with @ included
_ = *@int; // @int of type u (?), * not included, @ included
_ = &@int; // @int of type u (?), & not included, @ included You can also similarly mix Hereafter is my understanding of one of the cases mentioned above (to be verified): [DataRow("var [u:@int] = ([k:int]*)[k:null];_ = *[u:@int];", false)] Would it make sense to cover (some of) them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a couple of tests. The |
||
ClassifierTestHarness.AssertTokenTypes($$""" | ||
using System; | ||
public class C | ||
{ | ||
public unsafe void M(DateTime* dateTimePointer) | ||
{ | ||
{{statement}} | ||
} | ||
} | ||
""", allowSemanticModel); | ||
|
||
[DataTestMethod] | ||
[DataRow("[k:int] @int;", false)] | ||
[DataRow("[k:volatile] [t:@volatile] [u:@volatile];", false)] | ||
[DataRow("[t:Int32] [u:@someName];", false)] | ||
public void IdentifierToken_KeywordEscaping(string fieldDeclaration, bool allowSemanticModel) => | ||
ClassifierTestHarness.AssertTokenTypes($$""" | ||
using System; | ||
|
||
public class @volatile { } | ||
|
||
public class C | ||
{ | ||
{{fieldDeclaration}} | ||
} | ||
""", allowSemanticModel); | ||
} |
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.
Educational: this assertion still holds when using
using unsafe
from C# 12, right?Ptr
should still be consideredTokenType.UnknownTokentype
, and not a type. Correct?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 just works.
Ptr
is in a type position and is therefore classified as type (There is a distinguishing happening beforeClassifyMemberAccess
is called. AnIdentfierSymtax
can either be in an expression or a type context. In a type context, a single IdentfierName resolves to TokenType.TypeName and in an expression context to UnknownTokentype).