Right now, we have a path where if you call SyntaxFacts.ParseToken() you get back tokens that don't have a parent and thus don't belong to any syntax tree. That is odd. However, lexing a bunch of tokens without parsing them into anything specific is useful, for example, for performance reasons or because you just want a bunch of tokens without any error recovery performed by the parser (e.g. no inserted tokens).
To accommodate that, we allow queries to be empty. We parse an empty query into a CompilationUnitwhose Root property is null.
The semantics are:
Evaluating it as a query will produce zero rows with zero columns.
Evaluating it as an expression will produce a null value (when parsing expressions, we'll still produce a syntax error when the input is empty, but any query can be evaluated as an expression so we have to define this behavior also for expressions).
When parsing individual tokens, we parse them into a CompilationRoot whose Root property is null and all the tokens are contained as leading skipped token trivia for the end-of-file token. Thus, when flattening the tokens it will produce the input sequence but each token still has a defined parent and syntax tree. Also, the returned SyntaxTree is valid and can be bound and evaluated with the semantics above.
Right now, we have a path where if you call
SyntaxFacts.ParseToken()
you get back tokens that don't have a parent and thus don't belong to any syntax tree. That is odd. However, lexing a bunch of tokens without parsing them into anything specific is useful, for example, for performance reasons or because you just want a bunch of tokens without any error recovery performed by the parser (e.g. no inserted tokens).To accommodate that, we allow queries to be empty. We parse an empty query into a
CompilationUnit
whoseRoot
property isnull
.The semantics are:
null
value (when parsing expressions, we'll still produce a syntax error when the input is empty, but any query can be evaluated as an expression so we have to define this behavior also for expressions).When parsing individual tokens, we parse them into a
CompilationRoot
whoseRoot
property isnull
and all the tokens are contained as leading skipped token trivia for the end-of-file token. Thus, when flattening the tokens it will produce the input sequence but each token still has a defined parent and syntax tree. Also, the returnedSyntaxTree
is valid and can be bound and evaluated with the semantics above.