-
-
Notifications
You must be signed in to change notification settings - Fork 69
Description
The tree-sitter-csharp
parser fails and produces a root ERROR
node when encountering a C# attribute that is conditionally compiled using #if/#endif
, if the member (e.g., method, class) that the attribute applies to is not also enclosed within the same conditional compilation block.
Environment:
py-tree-sitter
version: 0.24.0tree-sitter-language-pack
version: 0.7.3tree-sitter-csharp
grammar version: 0.23.1tree-sitter-embedded-template
grammar version: 0.23.2- Operating System: macOS Sonoma 14.5
Minimal Reproducible Example:
// test_conditional_attribute.cs
namespace TestNs
{
public class TestClass
{
#if SOME_CONDITION // This can be any valid preprocessor symbol
[System.Obsolete("Conditional attribute")] // Attribute is conditional
#endif
public void MyMethod() // Method is NOT conditional in the same block
{
// Method body
}
}
}
Observed Behavior:
When parsing the above code, the tree.root_node.type
is ERROR
and tree.root_node.has_error
is True
. The error seems to encompass a large portion of the file, starting very early if this pattern appears near the top of a declaration.
Expected Behavior:
The parser should correctly parse this valid C# construct, associating the conditional attribute with MyMethod
if SOME_CONDITION
were true (tree-sitter parses structure, not evaluating defines), or parsing MyMethod
without the attribute if SOME_CONDITION
were false. The root node should be compilation_unit
and has_error
should be False
.
Note:
If the entire method declaration (including the attribute) is wrapped in the #if/#endif
block, it parses correctly:
// This parses correctly:
namespace TestNs
{
public class TestClass
{
#if SOME_CONDITION
[System.Obsolete("Conditional attribute")]
public void MyMethod()
{
// Method body
}
#endif
}
}
This suggests an issue with handling preprocessor directives that "interrupt" the expected contiguity between an attribute and the member it decorates. The grammar.js
for tree-sitter-csharp
often includes preprocessor directives in extras
, which should theoretically allow them in many places, but this specific pattern seems to expose a limitation.