(1) tasks/HOTFIXES.md: add 2026-05-20 entry for path-sanitize gap in
module_path_for_python / _tsjs (promised in task spec line 55 but
not landed in round 0). Bidirectional cross-link added.
(2) crates/kebab-parse-code: dedup filename_from_workspace_path /
strip_extension / join_symbol via new pub(crate) module scaffold.rs.
Removed 9 byte-identical fn copies across rust/python/typescript/
javascript extractors. Pure refactor — no behavior change.
(3) crates/kebab-parse-code/tests/fixtures/sample.py: @staticmethod was
semantically inappropriate on a module-level fn (class-method
decorator). Changed to @no_type_check; test assertion updated.
(5)+(6) crates/kebab-parse-code/src/lang.rs: add tests/test_foo.py case
to module_path_for_python test + doc clarifying that tests/ /
examples/ / benches/ are intentionally not stripped.
(4) PUSH BACK — TS/JS class decorator handling is design intent of 1B
1차 (typescript.rs:242-244 + HOTFIXES entry 2 already in place).
No code change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
46 lines
1.7 KiB
Rust
46 lines
1.7 KiB
Rust
//! `kebab-parse-code::scaffold` — shared pure helpers used by all
|
|
//! per-language extractor modules.
|
|
//!
|
|
//! These are `pub(crate)` utilities extracted from the four extractor
|
|
//! modules (rust / python / typescript / javascript) where identical
|
|
//! copies existed. Keeping them here is the single source of truth.
|
|
|
|
/// Extract the last path component (filename) from a `/`-separated
|
|
/// workspace path string.
|
|
/// For a path like `crates/x/src/foo.rs` this returns `foo.rs`.
|
|
pub(crate) fn filename_from_workspace_path(p: &str) -> String {
|
|
p.rsplit('/').next().unwrap_or(p).to_string()
|
|
}
|
|
|
|
/// Strip the last dot-extension from a filename string.
|
|
/// A leading dot (hidden-file convention) is preserved as-is.
|
|
/// `foo.rs` → `foo`, `.hidden` → `.hidden`, `noext` → `noext`.
|
|
pub(crate) fn strip_extension(filename: &str) -> String {
|
|
match filename.rfind('.') {
|
|
Some(0) => filename.to_string(),
|
|
Some(idx) => filename[..idx].to_string(),
|
|
None => filename.to_string(),
|
|
}
|
|
}
|
|
|
|
/// Join `(mod_prefix, mod_path, name)` into a dotted symbol string.
|
|
///
|
|
/// Used by Python / TypeScript / JavaScript extractors. Rust uses
|
|
/// `::` separators instead and builds symbols inline; this helper
|
|
/// covers the `.`-joined languages.
|
|
///
|
|
/// Empty `mod_prefix` (e.g. file is `__init__.py` at workspace root)
|
|
/// drops the leading prefix segment; empty `mod_path` (file top-level)
|
|
/// drops the class-nesting middle segment.
|
|
pub(crate) fn join_symbol(mod_prefix: &str, mod_path: &[String], name: &str) -> String {
|
|
let mut parts: Vec<&str> = Vec::with_capacity(mod_path.len() + 2);
|
|
if !mod_prefix.is_empty() {
|
|
parts.push(mod_prefix);
|
|
}
|
|
for p in mod_path {
|
|
parts.push(p.as_str());
|
|
}
|
|
parts.push(name);
|
|
parts.join(".")
|
|
}
|