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.0
tree-sitter-language-pack version: 0.7.3
tree-sitter-csharp grammar version: 0.23.1
tree-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.
The
tree-sitter-csharpparser fails and produces a rootERRORnode 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-sitterversion: 0.24.0tree-sitter-language-packversion: 0.7.3tree-sitter-csharpgrammar version: 0.23.1tree-sitter-embedded-templategrammar version: 0.23.2Minimal Reproducible Example:
Observed Behavior:
When parsing the above code, the
tree.root_node.typeisERRORandtree.root_node.has_errorisTrue. 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
MyMethodifSOME_CONDITIONwere true (tree-sitter parses structure, not evaluating defines), or parsingMyMethodwithout the attribute ifSOME_CONDITIONwere false. The root node should becompilation_unitandhas_errorshould beFalse.Note:
If the entire method declaration (including the attribute) is wrapped in the
#if/#endifblock, it parses correctly:This suggests an issue with handling preprocessor directives that "interrupt" the expected contiguity between an attribute and the member it decorates. The
grammar.jsfortree-sitter-csharpoften includes preprocessor directives inextras, which should theoretically allow them in many places, but this specific pattern seems to expose a limitation.