TS/JS: a call in a parameter's default value (`f(x = build())`) gets no calls edge

已关闭
#2,588 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

已经有一个关联 PR 被合并了。

  • #2753 来自 @inth3shadows —— 已关闭,未合并
  • #2802 来自 @colbymchenry —— 已合并

评估

难度
3/5
预计耗时
1-2 天
新手友好度
65/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
javascript, typescript, wasm
领域
devtools

调研方向

Start with the repro in the issue: a TypeScript file whose function has a parameter default containing a call, indexed with the WASM extractor. The two places named are extractFunction and extractMethod in src/extraction/tree-sitter.ts, which push the function node and walk only its body. Done means the calls edge from renderWithNote, the arrow function, K.m and destr to buildNote appears, and the existing in-body call edges still pass.

由索引模型根据 Issue 内容生成。

描述

Summary

A call written in a parameter default — function renderWithNote(note = buildNote()) — is not extracted at all: no calls edge and no unresolved reference. The same holds for arrow functions, class methods and destructured parameters with a default. buildNote therefore shows no caller from renderWithNote, and an impact query on buildNote misses it.

Reproduction (verified)

On main at 8fe31569, built from source, Linux (WSL2), Node 22.23.2, WASM extractor (CODEGRAPH_KERNEL=0).

src/f.ts

export function buildNote() { return { id: 1 }; }
export function renderWithNote(note = buildNote()) {
  return note.id;
}

codegraph init -i, then every edge that is not contains / imports / exports, and the unresolved refs:

-- edges
(none)
-- unresolved refs
(none)

The same empty result for:

export const arrow = (note = buildNote()) => note.id;
export class K { m(note = buildNote()) { return note.id; } }
export function destr({ n } = buildNote() as any) { return n; }

Control, same file: export function inBody() { const note = buildNote(); return note.id; } gets inBody -[calls L5]-> buildNote, so the call is only lost when it sits in a default.

Observed: no edge from renderWithNote (or arrow, K.m, destr) to buildNote.
Expected: renderWithNote -[calls]-> buildNote. A default is evaluated on every call that omits the argument, inside the function's own scope.

Likely cause (inferred from reading the code)

The grammar does put the call under the parameter ((required_parameter pattern: (identifier) value: (call_expression ...))), but the extractor pushes the function node and walks only its body:

I did not find any other place that visits the value of a required_parameter / optional_parameter / assignment_pattern for calls, which matches the empty unresolved_refs above (the call is never seen, rather than seen and left unresolved). Visiting each parameter's default value while the function node is still on nodeStack would attribute the call to the function.

Related

None found.

Not checked

  • The Rust kernel path (default, CODEGRAPH_KERNEL unset). Only the WASM extractor was run.
  • Other languages with default argument expressions (Python's def f(x=build()) is evaluated at definition time, so the right caller there is the enclosing scope rather than the function; Kotlin, Swift, C#, PHP and Ruby evaluate per call like JS).
  • new expressions and references (e.g. x = DEFAULT_CONST) in default values, which are probably missed the same way.
主要语言
C
星标
73.2k
派生
4.7k
平均合并
3 小时 39 分钟
30 天内合并 PR
528

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

colbymchenry/codegraph 的其他 Issue

查看 colbymchenry/codegraph 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。