From a399c9a60e6b3d0fe16786c1a9858a1f7a93221a Mon Sep 17 00:00:00 2001 From: Yunus Emre Umar <77045015+emre155@users.noreply.github.com> Date: Sun, 16 Aug 2026 17:00:14 +0300 Subject: [PATCH 1/4] fix(standards/cpp): support functor operator() and type conversion operators in func_start Closes #1752 --- gitgalaxy/standards/language_standards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitgalaxy/standards/language_standards.py b/gitgalaxy/standards/language_standards.py index 6402cf6a8..a60aa4e27 100644 --- a/gitgalaxy/standards/language_standards.py +++ b/gitgalaxy/standards/language_standards.py @@ -3032,7 +3032,7 @@ class PrismConfigSchema(TypedDict): # `(?:[a-zA-Z_]\w*::)*`. Out-of-line operator overload definitions (defined in a # .cpp file, declared in the header) are mainstream, common C++ -- completely # invisible to func_start before this fix. - r"(?![ \t]*#)((?:[a-zA-Z_]\w*::)*[~a-zA-Z_]\w*|(?:[a-zA-Z_]\w*::)*operator[ \t]*[^a-zA-Z_\s(]+|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:new|delete)(?:\[\])?)" + r"(?![ \t]*#)((?:[a-zA-Z_]\w*::)*[~a-zA-Z_]\w*|(?:[a-zA-Z_]\w*::)*operator[ \t]*\(\)|(?:[a-zA-Z_]\w*::)*operator[ \t]*[^a-zA-Z_\s(]+|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:new|delete)(?:\[\])?|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:::)?[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*(?:[ \t]*[*&]+)?)" # 7. THE PARAMETER BLOCK (Supports vertical gap) # [NESTED PARENTHESIS FIX]: Uses 1-Level Nesting Trick to swallow function pointers without ReDoS. r"[ \t\n]{0,200}(?:ARGS\d+\s*\([^)]*\)|\((?:[^)(]|\([^)]*\))*\)|NOARGS)" From e03e5b9fda22f2d3dde35c2d2673f745dcc5f8b9 Mon Sep 17 00:00:00 2001 From: Yunus Emre Umar <77045015+emre155@users.noreply.github.com> Date: Sun, 16 Aug 2026 18:22:57 +0300 Subject: [PATCH 2/4] fix(standards/cpp): shield operator from return-type consumer in func_start regex When parsing non-primitive conversion operators like MyClass::operator std::string(), the return type loop previously consumed MyClass::operator as a return type prefix, leaving only std::string captured as the function name. Add a negative lookahead to prevent the return type loop from consuming operator identifiers. Addresses part of #1752 --- gitgalaxy/standards/language_standards.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitgalaxy/standards/language_standards.py b/gitgalaxy/standards/language_standards.py index a60aa4e27..ea98b7671 100644 --- a/gitgalaxy/standards/language_standards.py +++ b/gitgalaxy/standards/language_standards.py @@ -3018,7 +3018,7 @@ class PrismConfigSchema(TypedDict): # literal `[*&]`, the other forbids consuming past the first # non-whitespace char), so this doesn't reopen the Rule 14 # backtracking gap the surrounding bounds were built to close. - r"(?:(?![ \t]*#)[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*" + r"(?:(?![ \t]*#)(?!(?:[a-zA-Z_]\w*::)*operator\b)[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*" r"(?:<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?" r"(?:[ \t]{0,20}[*&]{1,5}[ \t\n]{0,200}|[ \t\n]{1,200})){0,5}" # 5. THE "NOT A FUNCTION" SHIELD @@ -3032,7 +3032,7 @@ class PrismConfigSchema(TypedDict): # `(?:[a-zA-Z_]\w*::)*`. Out-of-line operator overload definitions (defined in a # .cpp file, declared in the header) are mainstream, common C++ -- completely # invisible to func_start before this fix. - r"(?![ \t]*#)((?:[a-zA-Z_]\w*::)*[~a-zA-Z_]\w*|(?:[a-zA-Z_]\w*::)*operator[ \t]*\(\)|(?:[a-zA-Z_]\w*::)*operator[ \t]*[^a-zA-Z_\s(]+|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:new|delete)(?:\[\])?|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:::)?[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*(?:[ \t]*[*&]+)?)" + r"(?![ \t]*#)((?:[a-zA-Z_]\w*::)*operator[ \t]*\(\)|(?:[a-zA-Z_]\w*::)*operator[ \t]*[^a-zA-Z_\s(]+|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:new|delete)(?:\[\])?|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:::)?[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*(?:[ \t]*[*&]+)?|(?:[a-zA-Z_]\w*::)*[~a-zA-Z_]\w*)" # 7. THE PARAMETER BLOCK (Supports vertical gap) # [NESTED PARENTHESIS FIX]: Uses 1-Level Nesting Trick to swallow function pointers without ReDoS. r"[ \t\n]{0,200}(?:ARGS\d+\s*\([^)]*\)|\((?:[^)(]|\([^)]*\))*\)|NOARGS)" From fa276765c5ce935304fd267165bb1488748cec0f Mon Sep 17 00:00:00 2001 From: Yunus Emre Umar <77045015+emre155@users.noreply.github.com> Date: Sun, 16 Aug 2026 18:23:11 +0300 Subject: [PATCH 3/4] test(cpp): add regression tests for functor and type conversion operators Addresses part of #1752 --- tests/extraction/languages/test_cpp.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/extraction/languages/test_cpp.py b/tests/extraction/languages/test_cpp.py index e95bf7df9..09c03d9e9 100644 --- a/tests/extraction/languages/test_cpp.py +++ b/tests/extraction/languages/test_cpp.py @@ -60,6 +60,22 @@ "TargetClass& TargetClass::operator=(const TargetClass& other) {", "TargetClass::operator=", ), # out-of-line operator= -- was a real bug, now fixed + ( + "MyClass::operator()() const {", + "MyClass::operator()", + ), # functor operator() + ( + "MyClass::operator bool() const {", + "MyClass::operator bool", + ), # primitive type conversion operator + ( + "MyClass::operator std::string() const {", + "MyClass::operator std::string", + ), # namespace-qualified type conversion operator + ( + "MyClass::operator Foo() const {", + "MyClass::operator Foo", + ), # custom type conversion operator ( "MyClass::MyClass(int x) : field_(x), other_(0) {", "MyClass::MyClass", From c3d8becf229988b5077e776ed42591d1d0e53bb7 Mon Sep 17 00:00:00 2001 From: Joe Esquibel Date: Sun, 16 Aug 2026 21:26:54 -0400 Subject: [PATCH 4/4] fix(cpp): fix argument parsing for operator overloads and update baselines --- gitgalaxy/core/detector.py | 2 +- gitgalaxy/standards/language_standards.py | 4 ++-- tests/tree_sitter_accuracy_baseline_cpp.json | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gitgalaxy/core/detector.py b/gitgalaxy/core/detector.py index 5b12a3627..166ad6d66 100644 --- a/gitgalaxy/core/detector.py +++ b/gitgalaxy/core/detector.py @@ -4445,7 +4445,7 @@ def _extract_name(self, raw_match: str) -> str: # Group 1 now grabs the optional `(Ident::)+` chain immediately # before the `operator` keyword and it's prefixed back on below. op_match = re.search( - r"((?:[a-zA-Z_]\w*::)*)\b(operator\s*(?:\[\s*\]|\(\s*\)|[^a-zA-Z0-9_\s({]+|[a-zA-Z_]\w*(?:\s*\*+)?))", + r"((?:[a-zA-Z_]\w*::)*)\b(operator\s*(?:\[\s*\]|\(\s*\)|(?:::)?[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*(?:\s*\*+)?|[^a-zA-Z0-9_\s({]+))", match_strip, ) if op_match: diff --git a/gitgalaxy/standards/language_standards.py b/gitgalaxy/standards/language_standards.py index c29eec4b7..ba7a105eb 100644 --- a/gitgalaxy/standards/language_standards.py +++ b/gitgalaxy/standards/language_standards.py @@ -36,7 +36,7 @@ | -------- | ----------- | -------------- | ------------ | --------------- | | Apex | 100.0% | 95.0% | 100.0% | 100.0% | | C | 93.3% | 99.5% | 100.0% | 100.0% | -| Cpp | 92.3% | 96.2% | 98.6% | 92.6% | +| Cpp | 93.4% | 95.7% | 98.6% | 92.6% | | Csharp | 99.2% | 99.8% | 100.0% | 100.0% | | Css | 100.0% | 100.0% | N/A | N/A | | Dart | 96.0% | 97.8% | 100.0% | 100.0% | @@ -3025,7 +3025,7 @@ class PrismConfigSchema(TypedDict): # `(?:[a-zA-Z_]\w*::)*`. Out-of-line operator overload definitions (defined in a # .cpp file, declared in the header) are mainstream, common C++ -- completely # invisible to func_start before this fix. - r"(?![ \t]*#)((?:[a-zA-Z_]\w*::)*operator[ \t]*\(\)|(?:[a-zA-Z_]\w*::)*operator[ \t]*[^a-zA-Z_\s(]+|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:new|delete)(?:\[\])?|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:::)?[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*(?:[ \t]*[*&]+)?|(?:[a-zA-Z_]\w*::)*[~a-zA-Z_]\w*)" + r"(?![ \t]*#)((?:[a-zA-Z_]\w*::)*operator[ \t]*\(\)|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:::)?[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*(?:[ \t]*[*&]+)?|(?:[a-zA-Z_]\w*::)*operator[ \t]*[^a-zA-Z_\s(]+|(?:[a-zA-Z_]\w*::)*operator[ \t]+(?:new|delete)(?:\[\])?|(?:[a-zA-Z_]\w*::)*[~a-zA-Z_]\w*)" # 7. THE PARAMETER BLOCK (Supports vertical gap) # [NESTED PARENTHESIS FIX]: Uses 1-Level Nesting Trick to swallow function pointers without ReDoS. r"[ \t\n]{0,200}(?:ARGS\d+\s*\([^)]*\)|\((?:[^)(]|\([^)]*\))*\)|NOARGS)" diff --git a/tests/tree_sitter_accuracy_baseline_cpp.json b/tests/tree_sitter_accuracy_baseline_cpp.json index 5117e554f..b0b916bb1 100644 --- a/tests/tree_sitter_accuracy_baseline_cpp.json +++ b/tests/tree_sitter_accuracy_baseline_cpp.json @@ -1,12 +1,12 @@ { - "args_comparable": 1376, - "args_exact_match": 1202, + "args_comparable": 1392, + "args_exact_match": 1207, "corpus_path": "language-crucible/data/cpp", "extra_classes": 11, - "extra_functions": 55, + "extra_functions": 62, "files_scanned": 29, "found_classes": 138, - "found_functions": 1376, + "found_functions": 1392, "real_classes": 140, "real_functions": 1491 }