diff --git a/gitgalaxy/core/detector.py b/gitgalaxy/core/detector.py index 3a7729a97..73e07bd5f 100644 --- a/gitgalaxy/core/detector.py +++ b/gitgalaxy/core/detector.py @@ -3323,6 +3323,13 @@ def _slice_by_braces( end_idx = self._find_balanced_end(safe_code, term_idx, opener, closer) args_sig_end = term_idx + 1 elif lang_id == "dart": + # #2341: func_start's match spans any leading `@annotation(...)` prefix + # and the return-type prefix, so `start_idx` can sit on an annotation + # whose own `(...)` (`@Deprecated('a' 'b',)` -- multi-line, with a + # top-level comma) is then the FIRST paren the args counter finds, + # poisoning the count. The real signature begins at the name capture; + # every args-span computation below anchors there instead of start_idx. + dart_name_start = match.start(match.lastindex) if match.lastindex else start_idx pos = match.end() has_parens = False while pos < next_match_start and pos < len(safe_code): @@ -3534,7 +3541,7 @@ def _dart_scan_terminator( # already validated real, balanced parens to get here) has # no such ambiguity. args_count_override = self._count_top_level_args( - safe_code[start_idx:params_end_idx], treat_as_body=False + safe_code[dart_name_start:params_end_idx], treat_as_body=False ) elif term_kind == "brace": end_idx = self._find_balanced_end(safe_code, term_idx, opener, closer) @@ -3832,7 +3839,11 @@ def _dart_scan_terminator( if not block: continue - args_search_text = code[start_idx:args_sig_end] if args_sig_end is not None else None + # #2341: for dart, anchor the args-signature slice at the name capture, not + # `start_idx` -- the latter can sit on a leading `@annotation(...)` whose own + # parens would otherwise be counted as the parameter list. + _args_slice_start = match.start(match.lastindex) if (lang_id == "dart" and match.lastindex) else start_idx + args_search_text = code[_args_slice_start:args_sig_end] if args_sig_end is not None else None # #2012: Pattern 2 - constructors with member-initializer-lists overcount. # Truncate at the first top-level `:` before the brace to exclude the list. diff --git a/tests/extraction/languages/test_dart.py b/tests/extraction/languages/test_dart.py index bc18df834..f925d9aa9 100644 --- a/tests/extraction/languages/test_dart.py +++ b/tests/extraction/languages/test_dart.py @@ -281,6 +281,38 @@ def test_dart_slicer_args_getters_and_operators_2309(): assert args_by_name.get("move") == 2, args_by_name # normal method unaffected +def test_dart_slicer_args_multiline_annotation_prefix_2341(): + """ + #2341: func_start's match spans a leading `@annotation(...)` prefix, so `start_idx` + lands on the annotation. When that annotation's argument list is multi-line and + carries a top-level comma (`@Deprecated('a' 'b',)`), its own parens were the first + the args counter found -- the declaration's real parameter list was never measured. + """ + from gitgalaxy.core.detector import StructuralExtractor + from gitgalaxy.standards.language_standards import LANGUAGE_DEFINITIONS + + splicer = StructuralExtractor("dart", LANGUAGE_DEFINITIONS) + code = ( + "class Opts {\n" + " @Deprecated(\n" + " 'Use somethingElse instead. '\n" + " 'Deprecated after v3.3.0.',\n" + " )\n" + " const Opts({this.a = false, this.b = false, this.c = false});\n" # -> 3 args + "\n" + " @Deprecated(\n" + " 'Gone. '\n" + " 'Deprecated after v3.9.0.',\n" + " )\n" + " bool get isReady => _ready;\n" # deprecated getter -> 0 args + "}\n" + ) + blocks, _ = splicer._slice_by_braces(code, "dart", DART_RULES, 0, {}) + args_by_name = {b["name"]: b.get("args") for b in blocks} + assert args_by_name.get("Opts") == 3, args_by_name + assert args_by_name.get("isReady") == 0, args_by_name + + def test_dart_slicer_bug_5_closure_invocation(): # Regression case for GitHub issue #1624: closure-arguments in calls were wrongly identified as functions. from gitgalaxy.core.detector import StructuralExtractor diff --git a/tests/golden_master_audit.json b/tests/golden_master_audit.json index 869f43a89..17f42f186 100644 --- a/tests/golden_master_audit.json +++ b/tests/golden_master_audit.json @@ -12,8 +12,8 @@ }, "Target Root Name": "data", "Absolute Project Path": "/home/joe/nyx_projects/language-crucible/data", - "Analysis ISO Timestamp": "2026-08-27T19:34:34.801325+00:00", - "Total Scan Duration": "34.12 seconds" + "Analysis ISO Timestamp": "2026-08-27T20:19:27.927795+00:00", + "Total Scan Duration": "34.14 seconds" }, "Source Control Footprint (Immutable Anchor)": { "Active Branch": "HEAD", @@ -310,7 +310,7 @@ "dart": { "files": 7, "loc": 22485, - "impact": 23338.5 + "impact": 23337.9 }, "go": { "files": 46, @@ -2218,7 +2218,7 @@ }, "dart/flutter": { "file_count": 7, - "total_mass": 23338.5, + "total_mass": 23337.9, "avg_exposures": { "cognitive_load": 19.68, "safety_score": 10.54, @@ -59568,7 +59568,7 @@ } }, "dart/flutter": { - "Directory Group Magnitude": 23338.5, + "Directory Group Magnitude": 23337.9, "File Count": 7, "Ecosystem Fingerprint (Archetypes)": { "Unclassified": "100.0%" @@ -59604,7 +59604,7 @@ "2. Topological Coordinates": { "X": -1827.16, "Y": 158.72, - "Z": -4112.08 + "Z": -4112.09 }, "3. Architectural Profile": { "Repository Archetype": "Unclassified", @@ -59616,7 +59616,7 @@ "Total LOC": 6793, "Coding LOC": 4168, "Documentation LOC": 2065, - "Structural Magnitude": 2917.26, + "Structural Magnitude": 2918.46, "Control Flow Ratio": "75.5%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -61210,6 +61210,16 @@ "Start Line": 6159, "End Line": 6165 }, + { + "Function Name": "ToolbarOptions", + "Structural Impact": 2.7, + "Lines of Code (LOC)": 10, + "Control Flow Branches": 0, + "Input Parameters": 4, + "Control Flow Ratio": "0.0%", + "Start Line": 405, + "End Line": 414 + }, { "Function Name": "initState", "Structural Impact": 2.6, @@ -61570,16 +61580,6 @@ "Start Line": 6253, "End Line": 6256 }, - { - "Function Name": "ToolbarOptions", - "Structural Impact": 1.5, - "Lines of Code (LOC)": 10, - "Control Flow Branches": 0, - "Input Parameters": 0, - "Control Flow Ratio": "0.0%", - "Start Line": 405, - "End Line": 414 - }, { "Function Name": "dx", "Structural Impact": 1.5, @@ -63898,7 +63898,7 @@ "Total LOC": 7456, "Coding LOC": 3380, "Documentation LOC": 3657, - "Structural Magnitude": 2017.0, + "Structural Magnitude": 2017.5, "Control Flow Ratio": "68.8%", "Popularity Rank": 3, "Raw Churn Frequency": 0.0, @@ -65952,6 +65952,16 @@ "Start Line": 6383, "End Line": 6387 }, + { + "Function Name": "RootRenderObjectElement", + "Structural Impact": 1.7, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 0, + "Input Parameters": 1, + "Control Flow Ratio": "0.0%", + "Start Line": 7017, + "End Line": 7021 + }, { "Function Name": "forgetChild", "Structural Impact": 1.7, @@ -66642,16 +66652,6 @@ "Start Line": 6823, "End Line": 6827 }, - { - "Function Name": "RootRenderObjectElement", - "Structural Impact": 1.2, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 0, - "Input Parameters": 0, - "Control Flow Ratio": "0.0%", - "Start Line": 7017, - "End Line": 7021 - }, { "Function Name": "debugDescribeChildren", "Structural Impact": 1.2, @@ -70208,7 +70208,7 @@ "Total LOC": 6760, "Coding LOC": 3910, "Documentation LOC": 2382, - "Structural Magnitude": 2382.4, + "Structural Magnitude": 2382.0, "Control Flow Ratio": "75.5%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -72442,16 +72442,6 @@ "Start Line": 303, "End Line": 308 }, - { - "Function Name": "debugOutstandingSemanticsHandles", - "Structural Impact": 1.7, - "Lines of Code (LOC)": 6, - "Control Flow Branches": 0, - "Input Parameters": 1, - "Control Flow Ratio": "0.0%", - "Start Line": 1372, - "End Line": 1377 - }, { "Function Name": "debugFillProperties", "Structural Impact": 1.7, @@ -72772,6 +72762,16 @@ "Start Line": 6344, "End Line": 6352 }, + { + "Function Name": "debugOutstandingSemanticsHandles", + "Structural Impact": 1.3, + "Lines of Code (LOC)": 6, + "Control Flow Branches": 0, + "Input Parameters": 0, + "Control Flow Ratio": "0.0%", + "Start Line": 1372, + "End Line": 1377 + }, { "Function Name": "runLayoutCallback", "Structural Impact": 1.3, @@ -73393,9 +73393,9 @@ "Identity Proof": "Single Indicator (Ext: .dart)" }, "2. Topological Coordinates": { - "X": -1467.95, + "X": -1467.96, "Y": 106.58, - "Z": -3106.0 + "Z": -3106.01 }, "3. Architectural Profile": { "Repository Archetype": "Unclassified", @@ -73407,7 +73407,7 @@ "Total LOC": 7176, "Coding LOC": 3893, "Documentation LOC": 2658, - "Structural Magnitude": 2826.26, + "Structural Magnitude": 2824.86, "Control Flow Ratio": "70.3%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -74751,16 +74751,6 @@ "Start Line": 6266, "End Line": 6267 }, - { - "Function Name": "isFocusable", - "Structural Impact": 3.1, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 1, - "Input Parameters": 1, - "Control Flow Ratio": "50.0%", - "Start Line": 6301, - "End Line": 6305 - }, { "Function Name": "textSelection", "Structural Impact": 3.1, @@ -75141,6 +75131,16 @@ "Start Line": 2671, "End Line": 2738 }, + { + "Function Name": "isFocusable", + "Structural Impact": 2.2, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 1, + "Input Parameters": 0, + "Control Flow Ratio": "50.0%", + "Start Line": 6301, + "End Line": 6305 + }, { "Function Name": "_redepthChildren", "Structural Impact": 2.1, @@ -76091,16 +76091,6 @@ "Start Line": 6337, "End Line": 6343 }, - { - "Function Name": "flags", - "Structural Impact": 1.7, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 0, - "Input Parameters": 1, - "Control Flow Ratio": "0.0%", - "Start Line": 1105, - "End Line": 1109 - }, { "Function Name": "hasFlag", "Structural Impact": 1.7, @@ -76651,6 +76641,16 @@ "Start Line": 874, "End Line": 877 }, + { + "Function Name": "flags", + "Structural Impact": 1.2, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 0, + "Input Parameters": 0, + "Control Flow Ratio": "0.0%", + "Start Line": 1105, + "End Line": 1109 + }, { "Function Name": "_generateNewId", "Structural Impact": 1.2, @@ -77666,7 +77666,7 @@ "Total LOC": 3490, "Coding LOC": 2305, "Documentation LOC": 985, - "Structural Magnitude": 6477.4, + "Structural Magnitude": 6476.9, "Control Flow Ratio": "85.0%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -78070,16 +78070,6 @@ "Start Line": 3088, "End Line": 3088 }, - { - "Function Name": "buttonBarTheme", - "Structural Impact": 1.7, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 0, - "Input Parameters": 1, - "Control Flow Ratio": "0.0%", - "Start Line": 1460, - "End Line": 1464 - }, { "Function Name": "debugFillProperties", "Structural Impact": 1.7, @@ -78110,6 +78100,16 @@ "Start Line": 3307, "End Line": 3314 }, + { + "Function Name": "buttonBarTheme", + "Structural Impact": 1.2, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 0, + "Input Parameters": 0, + "Control Flow Ratio": "0.0%", + "Start Line": 1460, + "End Line": 1464 + }, { "Function Name": "toStringShort", "Structural Impact": 1.2, diff --git a/tests/golden_master_zero_dep_audit.json b/tests/golden_master_zero_dep_audit.json index e3802a2a6..2974ef083 100644 --- a/tests/golden_master_zero_dep_audit.json +++ b/tests/golden_master_zero_dep_audit.json @@ -12,8 +12,8 @@ }, "Target Root Name": "data", "Absolute Project Path": "/home/joe/nyx_projects/language-crucible/data", - "Analysis ISO Timestamp": "2026-08-27T19:35:22.042189+00:00", - "Total Scan Duration": "32.11 seconds" + "Analysis ISO Timestamp": "2026-08-27T20:20:14.994314+00:00", + "Total Scan Duration": "32.08 seconds" }, "Source Control Footprint (Immutable Anchor)": { "Active Branch": "HEAD", @@ -310,7 +310,7 @@ "dart": { "files": 7, "loc": 22485, - "impact": 23338.5 + "impact": 23337.9 }, "go": { "files": 46, @@ -2218,7 +2218,7 @@ }, "dart/flutter": { "file_count": 7, - "total_mass": 23338.5, + "total_mass": 23337.9, "avg_exposures": { "cognitive_load": 19.68, "safety_score": 10.54, @@ -59568,7 +59568,7 @@ } }, "dart/flutter": { - "Directory Group Magnitude": 23338.5, + "Directory Group Magnitude": 23337.9, "File Count": 7, "Ecosystem Fingerprint (Archetypes)": { "Unclassified": "100.0%" @@ -59604,7 +59604,7 @@ "2. Topological Coordinates": { "X": -1827.16, "Y": 158.72, - "Z": -4112.08 + "Z": -4112.09 }, "3. Architectural Profile": { "Repository Archetype": "Unclassified", @@ -59616,7 +59616,7 @@ "Total LOC": 6793, "Coding LOC": 4168, "Documentation LOC": 2065, - "Structural Magnitude": 2917.26, + "Structural Magnitude": 2918.46, "Control Flow Ratio": "75.5%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -61210,6 +61210,16 @@ "Start Line": 6159, "End Line": 6165 }, + { + "Function Name": "ToolbarOptions", + "Structural Impact": 2.7, + "Lines of Code (LOC)": 10, + "Control Flow Branches": 0, + "Input Parameters": 4, + "Control Flow Ratio": "0.0%", + "Start Line": 405, + "End Line": 414 + }, { "Function Name": "initState", "Structural Impact": 2.6, @@ -61570,16 +61580,6 @@ "Start Line": 6253, "End Line": 6256 }, - { - "Function Name": "ToolbarOptions", - "Structural Impact": 1.5, - "Lines of Code (LOC)": 10, - "Control Flow Branches": 0, - "Input Parameters": 0, - "Control Flow Ratio": "0.0%", - "Start Line": 405, - "End Line": 414 - }, { "Function Name": "dx", "Structural Impact": 1.5, @@ -63898,7 +63898,7 @@ "Total LOC": 7456, "Coding LOC": 3380, "Documentation LOC": 3657, - "Structural Magnitude": 2017.0, + "Structural Magnitude": 2017.5, "Control Flow Ratio": "68.8%", "Popularity Rank": 4, "Raw Churn Frequency": 0.0, @@ -65952,6 +65952,16 @@ "Start Line": 6383, "End Line": 6387 }, + { + "Function Name": "RootRenderObjectElement", + "Structural Impact": 1.7, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 0, + "Input Parameters": 1, + "Control Flow Ratio": "0.0%", + "Start Line": 7017, + "End Line": 7021 + }, { "Function Name": "forgetChild", "Structural Impact": 1.7, @@ -66642,16 +66652,6 @@ "Start Line": 6823, "End Line": 6827 }, - { - "Function Name": "RootRenderObjectElement", - "Structural Impact": 1.2, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 0, - "Input Parameters": 0, - "Control Flow Ratio": "0.0%", - "Start Line": 7017, - "End Line": 7021 - }, { "Function Name": "debugDescribeChildren", "Structural Impact": 1.2, @@ -70208,7 +70208,7 @@ "Total LOC": 6760, "Coding LOC": 3910, "Documentation LOC": 2382, - "Structural Magnitude": 2382.4, + "Structural Magnitude": 2382.0, "Control Flow Ratio": "75.5%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -72442,16 +72442,6 @@ "Start Line": 303, "End Line": 308 }, - { - "Function Name": "debugOutstandingSemanticsHandles", - "Structural Impact": 1.7, - "Lines of Code (LOC)": 6, - "Control Flow Branches": 0, - "Input Parameters": 1, - "Control Flow Ratio": "0.0%", - "Start Line": 1372, - "End Line": 1377 - }, { "Function Name": "debugFillProperties", "Structural Impact": 1.7, @@ -72772,6 +72762,16 @@ "Start Line": 6344, "End Line": 6352 }, + { + "Function Name": "debugOutstandingSemanticsHandles", + "Structural Impact": 1.3, + "Lines of Code (LOC)": 6, + "Control Flow Branches": 0, + "Input Parameters": 0, + "Control Flow Ratio": "0.0%", + "Start Line": 1372, + "End Line": 1377 + }, { "Function Name": "runLayoutCallback", "Structural Impact": 1.3, @@ -73393,9 +73393,9 @@ "Identity Proof": "Single Indicator (Ext: .dart)" }, "2. Topological Coordinates": { - "X": -1467.95, + "X": -1467.96, "Y": 106.58, - "Z": -3106.0 + "Z": -3106.01 }, "3. Architectural Profile": { "Repository Archetype": "Unclassified", @@ -73407,7 +73407,7 @@ "Total LOC": 7176, "Coding LOC": 3893, "Documentation LOC": 2658, - "Structural Magnitude": 2826.26, + "Structural Magnitude": 2824.86, "Control Flow Ratio": "70.3%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -74751,16 +74751,6 @@ "Start Line": 6266, "End Line": 6267 }, - { - "Function Name": "isFocusable", - "Structural Impact": 3.1, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 1, - "Input Parameters": 1, - "Control Flow Ratio": "50.0%", - "Start Line": 6301, - "End Line": 6305 - }, { "Function Name": "textSelection", "Structural Impact": 3.1, @@ -75141,6 +75131,16 @@ "Start Line": 2671, "End Line": 2738 }, + { + "Function Name": "isFocusable", + "Structural Impact": 2.2, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 1, + "Input Parameters": 0, + "Control Flow Ratio": "50.0%", + "Start Line": 6301, + "End Line": 6305 + }, { "Function Name": "_redepthChildren", "Structural Impact": 2.1, @@ -76091,16 +76091,6 @@ "Start Line": 6337, "End Line": 6343 }, - { - "Function Name": "flags", - "Structural Impact": 1.7, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 0, - "Input Parameters": 1, - "Control Flow Ratio": "0.0%", - "Start Line": 1105, - "End Line": 1109 - }, { "Function Name": "hasFlag", "Structural Impact": 1.7, @@ -76651,6 +76641,16 @@ "Start Line": 874, "End Line": 877 }, + { + "Function Name": "flags", + "Structural Impact": 1.2, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 0, + "Input Parameters": 0, + "Control Flow Ratio": "0.0%", + "Start Line": 1105, + "End Line": 1109 + }, { "Function Name": "_generateNewId", "Structural Impact": 1.2, @@ -77666,7 +77666,7 @@ "Total LOC": 3490, "Coding LOC": 2305, "Documentation LOC": 985, - "Structural Magnitude": 6477.4, + "Structural Magnitude": 6476.9, "Control Flow Ratio": "85.0%", "Popularity Rank": 0, "Raw Churn Frequency": 0.0, @@ -78070,16 +78070,6 @@ "Start Line": 3088, "End Line": 3088 }, - { - "Function Name": "buttonBarTheme", - "Structural Impact": 1.7, - "Lines of Code (LOC)": 5, - "Control Flow Branches": 0, - "Input Parameters": 1, - "Control Flow Ratio": "0.0%", - "Start Line": 1460, - "End Line": 1464 - }, { "Function Name": "debugFillProperties", "Structural Impact": 1.7, @@ -78110,6 +78100,16 @@ "Start Line": 3307, "End Line": 3314 }, + { + "Function Name": "buttonBarTheme", + "Structural Impact": 1.2, + "Lines of Code (LOC)": 5, + "Control Flow Branches": 0, + "Input Parameters": 0, + "Control Flow Ratio": "0.0%", + "Start Line": 1460, + "End Line": 1464 + }, { "Function Name": "toStringShort", "Structural Impact": 1.2, diff --git a/tests/tree_sitter_accuracy_baseline_dart.json b/tests/tree_sitter_accuracy_baseline_dart.json index 2337da143..fe539080e 100644 --- a/tests/tree_sitter_accuracy_baseline_dart.json +++ b/tests/tree_sitter_accuracy_baseline_dart.json @@ -1,6 +1,6 @@ { "args_comparable": 1739, - "args_exact_match": 1733, + "args_exact_match": 1739, "corpus_path": "language-crucible/data/dart", "extra_classes": 0, "extra_functions": 12,