From 3d283157bc40442d5b9f12e21ef13342ccf23f35 Mon Sep 17 00:00:00 2001 From: nohehf Date: Mon, 27 May 2024 09:47:41 +0200 Subject: [PATCH 1/3] fix: ignore .ts and .js extensions form imports --- .../src/stack-graphs.tsg | 6 ++++-- .../test/modules/import-extension-js.ts | 6 ++++++ .../test/modules/import-extension-none.ts | 6 ++++++ .../test/modules/import-extension-ts.ts | 6 ++++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-js.ts create mode 100644 languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-none.ts create mode 100644 languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-ts.ts diff --git a/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg index fa1cbf8f8..a51a80c07 100644 --- a/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg @@ -260,7 +260,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ; expose globals edge proj_scope -> @prog.globals - + var mod_scope = proj_scope if (not (is-empty @imexs)) { ; module definition @@ -541,7 +541,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n ; module reference var mod_scope = mod_ref__ns scan (path-normalize mod_path) { - "([^/]+)/?" { + ; ignore .js and .ts extensions on imports, as ts allows this + ; this might lead to false positives + "([^/|(\.j|ts)]+)/?" { node mod_ref attr (mod_ref) push_symbol = $1 edge mod_ref -> mod_scope diff --git a/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-js.ts b/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-js.ts new file mode 100644 index 000000000..92817fbaf --- /dev/null +++ b/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-js.ts @@ -0,0 +1,6 @@ +/* --- path: src/foo.ts --- */ +export const bar = 42; + +/* --- path: src/index.ts --- */ +import { bar } from "./foo.js"; +// ^ defined: 2 diff --git a/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-none.ts b/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-none.ts new file mode 100644 index 000000000..f221684b4 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-none.ts @@ -0,0 +1,6 @@ +/* --- path: src/foo.ts --- */ +export const bar = 42; + +/* --- path: src/index.ts --- */ +import { bar } from "./foo"; +// ^ defined: 2 diff --git a/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-ts.ts b/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-ts.ts new file mode 100644 index 000000000..1e46349c9 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-typescript/test/modules/import-extension-ts.ts @@ -0,0 +1,6 @@ +/* --- path: src/foo.ts --- */ +export const bar = 42; + +/* --- path: src/index.ts --- */ +import { bar } from "./foo.ts"; +// ^ defined: 2 From d0b940e66c0e0c2d83533cc743d30142e4728585 Mon Sep 17 00:00:00 2001 From: nohehf Date: Mon, 27 May 2024 15:46:23 +0200 Subject: [PATCH 2/3] fix: add auxiliary function to remove file ext --- .../src/stack-graphs.tsg | 9 ++--- tree-sitter-stack-graphs/src/functions.rs | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg index a51a80c07..7e6359280 100644 --- a/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg @@ -260,7 +260,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ; expose globals edge proj_scope -> @prog.globals - + var mod_scope = proj_scope if (not (is-empty @imexs)) { ; module definition @@ -540,10 +540,9 @@ attribute node_symbol = node => symbol = (source-text node), source_n ; module reference var mod_scope = mod_ref__ns - scan (path-normalize mod_path) { - ; ignore .js and .ts extensions on imports, as ts allows this - ; this might lead to false positives - "([^/|(\.j|ts)]+)/?" { + ; normalize path and remove the extension as we want to match 'foo', 'foo.js', 'foo.ts', etc. + scan (path-remove-ext (path-normalize mod_path)) { + "([^/]+)/?" { node mod_ref attr (mod_ref) push_symbol = $1 edge mod_ref -> mod_scope diff --git a/tree-sitter-stack-graphs/src/functions.rs b/tree-sitter-stack-graphs/src/functions.rs index 9082ba427..e1f9e94e5 100644 --- a/tree-sitter-stack-graphs/src/functions.rs +++ b/tree-sitter-stack-graphs/src/functions.rs @@ -43,6 +43,10 @@ pub mod path { path_fn(|p| normalize(p).map(|p| p.as_os_str().to_os_string())), ); functions.add("path-split".into(), PathSplit); + functions.add( + "path-remove-ext".into(), + path_fn(|p| remove_extension(p).map(|p| p.as_os_str().to_os_string())), + ); } pub fn path_fn(f: F) -> impl Function @@ -159,4 +163,37 @@ pub mod path { } Some(ret) } + + /// Removes the extension from a path. + /// eg. `foo/bar.rs` -> `foo/bar` + /// eg. `foo/bar` -> `foo/bar` + /// eg. `foo/bar.rs.bak` -> `foo/bar.rs` + pub fn remove_extension(path: &Path) -> Option { + path.extension() + .map_or(Some(path.into()), |_| path.with_extension("").into()) + } + + #[test] + fn test_remove_extension() { + assert_eq!( + remove_extension(Path::new("foo/bar.rs")), + Some(PathBuf::from("foo/bar")) + ); + assert_eq!( + remove_extension(Path::new("foo/bar")), + Some(PathBuf::from("foo/bar")) + ); + assert_eq!( + remove_extension(Path::new("foo/bar.rs.bak")), + Some(PathBuf::from("foo/bar.rs")) + ); + assert_eq!( + remove_extension(Path::new("foo")), + Some(PathBuf::from("foo")) + ); + assert_eq!( + remove_extension(Path::new("foo.rs")), + Some(PathBuf::from("foo")) + ); + } } From c43fa8b1af2a5ced2174059d41d4b0f2b8da3983 Mon Sep 17 00:00:00 2001 From: nohehf Date: Thu, 30 May 2024 11:36:09 +0200 Subject: [PATCH 3/3] feat: use replace instead of custom function --- .../src/stack-graphs.tsg | 2 +- tree-sitter-stack-graphs/src/functions.rs | 37 ------------------- 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg index 7e6359280..b7478b4e4 100644 --- a/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg @@ -541,7 +541,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n ; module reference var mod_scope = mod_ref__ns ; normalize path and remove the extension as we want to match 'foo', 'foo.js', 'foo.ts', etc. - scan (path-remove-ext (path-normalize mod_path)) { + scan (path-normalize (replace mod_path "\.(js|ts|jsx|tsx)$" "")) { "([^/]+)/?" { node mod_ref attr (mod_ref) push_symbol = $1 diff --git a/tree-sitter-stack-graphs/src/functions.rs b/tree-sitter-stack-graphs/src/functions.rs index e1f9e94e5..9082ba427 100644 --- a/tree-sitter-stack-graphs/src/functions.rs +++ b/tree-sitter-stack-graphs/src/functions.rs @@ -43,10 +43,6 @@ pub mod path { path_fn(|p| normalize(p).map(|p| p.as_os_str().to_os_string())), ); functions.add("path-split".into(), PathSplit); - functions.add( - "path-remove-ext".into(), - path_fn(|p| remove_extension(p).map(|p| p.as_os_str().to_os_string())), - ); } pub fn path_fn(f: F) -> impl Function @@ -163,37 +159,4 @@ pub mod path { } Some(ret) } - - /// Removes the extension from a path. - /// eg. `foo/bar.rs` -> `foo/bar` - /// eg. `foo/bar` -> `foo/bar` - /// eg. `foo/bar.rs.bak` -> `foo/bar.rs` - pub fn remove_extension(path: &Path) -> Option { - path.extension() - .map_or(Some(path.into()), |_| path.with_extension("").into()) - } - - #[test] - fn test_remove_extension() { - assert_eq!( - remove_extension(Path::new("foo/bar.rs")), - Some(PathBuf::from("foo/bar")) - ); - assert_eq!( - remove_extension(Path::new("foo/bar")), - Some(PathBuf::from("foo/bar")) - ); - assert_eq!( - remove_extension(Path::new("foo/bar.rs.bak")), - Some(PathBuf::from("foo/bar.rs")) - ); - assert_eq!( - remove_extension(Path::new("foo")), - Some(PathBuf::from("foo")) - ); - assert_eq!( - remove_extension(Path::new("foo.rs")), - Some(PathBuf::from("foo")) - ); - } }