mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-29 14:49:36 +08:00
fix(rust): framework name heuristics never reach a function-local item (#2224)
The Rust resolver's handler/service/struct heuristics took the first same-named item and then checked scope; they now drop items declared inside a function body and out-of-scope names before choosing, and take the file's own item first. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ca1eba98bd
commit
7365427d4f
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* The Rust resolver's struct/handler/service name heuristics never reach an
|
||||
* item declared inside a function body — axum's examples' `Uri` (imported
|
||||
* from `http`) went to a `struct Uri` a routing test declares inside itself —
|
||||
* and a file's own item comes first: ripgrep's `Ok(Glob { … })` in
|
||||
* globset's glob.rs is its own `Glob`, not the CLI flags' `Glob`.
|
||||
*/
|
||||
import { describe, it, expect, afterAll, beforeAll } from 'vitest';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { CodeGraph } from '../src';
|
||||
|
||||
let root = '';
|
||||
let cg: CodeGraph;
|
||||
|
||||
beforeAll(async () => {
|
||||
root = fs.mkdtempSync(path.join(os.tmpdir(), 'cg-rust-fw-'));
|
||||
const files: Record<string, string> = {
|
||||
'Cargo.toml': '[workspace]\nmembers = ["crates/core", "crates/globset", "crates/web", "examples/tls"]\n',
|
||||
'crates/core/Cargo.toml': '[package]\nname = "rg-core"\n',
|
||||
'crates/web/Cargo.toml': '[package]\nname = "web"\n',
|
||||
'crates/web/src/lib.rs': 'pub mod http;\n',
|
||||
'crates/web/src/http.rs': 'pub use ::http::Uri;\n',
|
||||
'crates/web/src/routing/tests.rs': `fn outer_middleware_still_see_whole_url() {
|
||||
struct Uri;
|
||||
let _ = Uri;
|
||||
}
|
||||
`,
|
||||
'examples/tls/Cargo.toml': '[package]\nname = "example-tls"\n\n[dependencies]\nweb = { path = "../../crates/web" }\n',
|
||||
'examples/tls/src/main.rs': `use web::http::Uri;
|
||||
|
||||
fn make_https(uri: Uri, port: u16) -> Uri {
|
||||
uri
|
||||
}
|
||||
`,
|
||||
'crates/core/src/flags/defs.rs': `pub struct Glob;
|
||||
|
||||
pub fn glob_flag() -> Glob {
|
||||
Glob
|
||||
}
|
||||
`,
|
||||
'crates/globset/Cargo.toml': '[package]\nname = "globset"\n',
|
||||
'crates/globset/src/glob.rs': `pub struct Glob {
|
||||
glob: String,
|
||||
}
|
||||
|
||||
impl Glob {
|
||||
pub fn new(glob: &str) -> Result<Glob, ()> {
|
||||
Ok(Glob { glob: glob.to_string() })
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
for (const [rel, content] of Object.entries(files)) {
|
||||
fs.mkdirSync(path.dirname(path.join(root, rel)), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, rel), content);
|
||||
}
|
||||
cg = await CodeGraph.init(root, { index: true });
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
cg?.close();
|
||||
if (root) fs.rmSync(root, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
const targetsFrom = (file: string) => {
|
||||
const ids = cg.getNodesInFile(file).map((n) => n.id);
|
||||
return cg.getOutgoingEdgesFrom(ids).filter((e) => e.kind !== 'contains')
|
||||
.map((e) => cg.getNode(e.target)!).map((t) => `${t.filePath}:${t.qualifiedName}`);
|
||||
};
|
||||
|
||||
describe('Rust framework name heuristics', () => {
|
||||
it('never reach an item declared inside a function body', () => {
|
||||
expect(targetsFrom('examples/tls/src/main.rs').filter((t) => t.includes('outer_middleware'))).toEqual([]);
|
||||
});
|
||||
|
||||
it('take the file’s own item first', () => {
|
||||
const globs = targetsFrom('crates/globset/src/glob.rs').filter((t) => t.endsWith(':Glob'));
|
||||
expect(globs.length).toBeGreaterThan(0);
|
||||
expect(new Set(globs)).toEqual(new Set(['crates/globset/src/glob.rs:Glob']));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user