tree-sitter / tree-sitter/tree-sitter-cpp
Incorrect query matches on a condition including "typeid"
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 453
- Forks
- 185
- PR merge metrics
- No merged PRs in 30d
Description
Dear Community,
I receive an incorrect query-capture using the treesitter api on a rare if-statement edge case. I want to grab the condition inside an if-statement. In this particular case, there is an if-statement, that contains the keyword "typeid". This leads to an incorrect grab, it doesnt find the end of the if-statement correctly and parses until the next if-statement finishes.
My Setup:
Win10
py3.8
tree-sitter-python with compiled tree-sitter-cpp language
I am using this query in order to grab the condition inside the if-statement:
DEFAULT_QUERY = "(if_statement(condition_clause)@if_statement)"
this works really well every case I tried out except one (admittedly rare) case I encountered so far. Consider this valid c++:
bool including_namespace_identifier_and_primitive_type(int x, int y) {
if(std::strcmp(typeid(unsigned int).name(), something_else)))
return false;
// this is a comment that will be included IN THE result of the query!
if(the.catched.condition.will.include.this_statement)
return false;
doSomething();
return true;
}
using the query above and code[capture.start_byte : capture.stop_byte] we get this captured continous statement:
(std::strcmp(typeid(unsigned int).name(), something_else)))
return false;
// this is a comment that will be included IN THE result of the query!
if(the.catched.condition.will.include.this_statement)
Instead of getting two seperate statements. I am not into generating valid grammar files so far, I hope its an easy fix for someone.
Example where this kind of c++ is used: https://github.com/apple/turicreate/blob/master/src/external/boost/boost_1_68_0/libs/interprocess/test/segment_manager_test.cpp#L337
---------------------------------------------- Some more Notes ----------------------------
If I delete the typeid it works as intended, see:
bool including_namespace_identifier_and_primitive_type(int x, int y) {
if(std::strcmp((unsigned int).name()))
return false;
// this is a comment that will be included IN THE result of the query!
if(the.catched.condition.will.include.this_statement)
return false;
doSomething();
return true;
}
This finds two seperate statments:
(std::strcmp((unsigned int).name()))
(the.catched.condition.will.include.this_statement)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the provided C++ example and DEFAULT_QUERY against the tree-sitter-cpp grammar, comparing the captures with and without typeid. Inspect the grammar files involved in parsing if conditions and typeid expressions, then add a regression case showing that both condition clauses end at the correct boundaries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100