Skip to content

Commit 3b11a8a

Browse files
committed
fix(native): extract parameters for prototype methods (#1345)
1 parent 874e8fd commit 3b11a8a

1 file changed

Lines changed: 45 additions & 8 deletions

File tree

crates/codegraph-core/src/extractors/javascript.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ fn emit_js_prototype_method(class_name: &str, method_name: &str, rhs: &Node, sou
362362
let full_name = format!("{}.{}", class_name, method_name);
363363
match rhs.kind() {
364364
"function_expression" | "arrow_function" => {
365+
let children = extract_js_parameters(rhs, source);
365366
symbols.definitions.push(Definition {
366367
name: full_name,
367368
kind: "method".to_string(),
@@ -370,7 +371,7 @@ fn emit_js_prototype_method(class_name: &str, method_name: &str, rhs: &Node, sou
370371
decorators: None,
371372
complexity: compute_all_metrics(rhs, source, "javascript"),
372373
cfg: build_function_cfg(rhs, "javascript", source),
373-
children: None,
374+
children: opt_children(children),
374375
});
375376
}
376377
"identifier" => {
@@ -392,6 +393,7 @@ fn extract_js_prototype_object_literal(class_name: &str, obj_node: &Node, source
392393
match child.kind() {
393394
"method_definition" => {
394395
let Some(name_node) = child.child_by_field_name("name") else { continue };
396+
let children = extract_js_parameters(&child, source);
395397
symbols.definitions.push(Definition {
396398
name: format!("{}.{}", class_name, node_text(&name_node, source)),
397399
kind: "method".to_string(),
@@ -400,7 +402,7 @@ fn extract_js_prototype_object_literal(class_name: &str, obj_node: &Node, source
400402
decorators: None,
401403
complexity: compute_all_metrics(&child, source, "javascript"),
402404
cfg: build_function_cfg(&child, "javascript", source),
403-
children: None,
405+
children: opt_children(children),
404406
});
405407
}
406408
"shorthand_property_identifier" => {
@@ -2506,39 +2508,74 @@ mod tests {
25062508
}
25072509

25082510
#[test]
2509-
fn prototype_direct_method_has_complexity_and_cfg() {
2511+
fn prototype_direct_method_has_complexity_cfg_and_children() {
25102512
let s = parse_js(
25112513
"function C() {}\n\
2512-
C.prototype.foo = function() { if (true) { return 1; } return 0; };",
2514+
C.prototype.foo = function(x, y) { if (true) { return 1; } return 0; };",
25132515
);
25142516
let def = s.definitions.iter().find(|d| d.name == "C.foo").expect("C.foo missing");
25152517
assert!(def.complexity.is_some(), "C.foo should have complexity metrics");
25162518
assert!(def.cfg.is_some(), "C.foo should have CFG data");
2519+
let children = def.children.as_deref().unwrap_or(&[]);
2520+
assert!(
2521+
children.iter().any(|c| c.name == "x"),
2522+
"C.foo should have parameter 'x'; got: {:?}", children
2523+
);
2524+
assert!(
2525+
children.iter().any(|c| c.name == "y"),
2526+
"C.foo should have parameter 'y'; got: {:?}", children
2527+
);
2528+
}
2529+
2530+
#[test]
2531+
fn prototype_direct_arrow_has_complexity_cfg_and_children() {
2532+
let s = parse_js(
2533+
"function C() {}\n\
2534+
C.prototype.bar = (a, b) => a > 0 ? a : b;",
2535+
);
2536+
let def = s.definitions.iter().find(|d| d.name == "C.bar").expect("C.bar missing");
2537+
assert!(def.complexity.is_some(), "C.bar arrow should have complexity metrics");
2538+
assert!(def.cfg.is_some(), "C.bar arrow should have CFG data");
2539+
let children = def.children.as_deref().unwrap_or(&[]);
2540+
assert!(
2541+
children.iter().any(|c| c.name == "a"),
2542+
"C.bar should have parameter 'a'; got: {:?}", children
2543+
);
25172544
}
25182545

25192546
#[test]
2520-
fn prototype_object_literal_method_definition_has_complexity_and_cfg() {
2547+
fn prototype_object_literal_method_definition_has_complexity_cfg_and_children() {
25212548
let s = parse_js(
25222549
"function C() {}\n\
25232550
C.prototype = {\n\
2524-
greet() { if (true) { return 'hi'; } return ''; },\n\
2551+
greet(name) { if (true) { return 'hi'; } return ''; },\n\
25252552
};",
25262553
);
25272554
let def = s.definitions.iter().find(|d| d.name == "C.greet").expect("C.greet missing");
25282555
assert!(def.complexity.is_some(), "C.greet should have complexity metrics");
25292556
assert!(def.cfg.is_some(), "C.greet should have CFG data");
2557+
let children = def.children.as_deref().unwrap_or(&[]);
2558+
assert!(
2559+
children.iter().any(|c| c.name == "name"),
2560+
"C.greet should have parameter 'name'; got: {:?}", children
2561+
);
25302562
}
25312563

25322564
#[test]
2533-
fn prototype_object_literal_pair_fn_has_complexity_and_cfg() {
2565+
fn prototype_object_literal_pair_fn_has_complexity_cfg_and_children() {
25342566
let s = parse_js(
25352567
"function C() {}\n\
25362568
C.prototype = {\n\
2537-
bar: function() { if (true) { return 1; } return 0; },\n\
2569+
bar: function(n) { if (true) { return 1; } return 0; },\n\
25382570
};",
25392571
);
25402572
let def = s.definitions.iter().find(|d| d.name == "C.bar").expect("C.bar missing");
25412573
assert!(def.complexity.is_some(), "C.bar should have complexity metrics");
25422574
assert!(def.cfg.is_some(), "C.bar should have CFG data");
2575+
let children = def.children.as_deref().unwrap_or(&[]);
2576+
assert!(
2577+
children.iter().any(|c| c.name == "n"),
2578+
"C.bar should have parameter 'n'; got: {:?}", children
2579+
);
25432580
}
25442581
}

0 commit comments

Comments
 (0)