Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit 488bb23

Browse files
author
Hendrik van Antwerpen
committed
Add simple package.json analyzer
1 parent 26a7f40 commit 488bb23

File tree

7 files changed

+128
-16
lines changed

7 files changed

+128
-16
lines changed

languages/tree-sitter-stack-graphs-typescript/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ harness = false
2525
anyhow = "1.0"
2626
clap = "3"
2727
glob = "0.3"
28+
serde = { version = "1.0", features = ["derive"] }
29+
serde_json = "1.0"
2830
stack-graphs = { version = "~0.10", path = "../../stack-graphs" }
2931
tree-sitter-stack-graphs = { version = "~0.5", path = "../../tree-sitter-stack-graphs", features=["cli"] }
3032
tree-sitter-typescript = { git = "https://github.com/tree-sitter/tree-sitter-typescript", rev="082da44a5263599186dadafd2c974c19f3a73d28" }

languages/tree-sitter-stack-graphs-typescript/rust/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
66
// ------------------------------------------------------------------------------------------------
77

8-
use crate::tsconfig::TsConfigAnalyzer;
98
use tree_sitter_stack_graphs::loader::FileAnalyzers;
109
use tree_sitter_stack_graphs::loader::LanguageConfiguration;
1110
use tree_sitter_stack_graphs::CancellationFlag;
1211

12+
use crate::npm_package::NpmPackageAnalyzer;
13+
use crate::tsconfig::TsConfigAnalyzer;
14+
15+
pub mod npm_package;
1316
pub mod tsconfig;
1417
pub mod util;
1518

@@ -35,7 +38,9 @@ pub fn language_configuration(cancellation_flag: &dyn CancellationFlag) -> Langu
3538
STACK_GRAPHS_TSG_SOURCE,
3639
Some(STACK_GRAPHS_BUILTINS_SOURCE),
3740
Some(STACK_GRAPHS_BUILTINS_CONFIG),
38-
FileAnalyzers::new().add("tsconfig.json".to_string(), TsConfigAnalyzer {}),
41+
FileAnalyzers::new()
42+
.add("tsconfig.json".to_string(), TsConfigAnalyzer {})
43+
.add("package.json".to_string(), NpmPackageAnalyzer {}),
3944
cancellation_flag,
4045
)
4146
.unwrap()
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// -*- coding: utf-8 -*-
2+
// ------------------------------------------------------------------------------------------------
3+
// Copyright © 2022, stack-graphs authors.
4+
// Licensed under either of Apache License, Version 2.0, or MIT license, at your option.
5+
// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
6+
// ------------------------------------------------------------------------------------------------
7+
8+
use serde::Deserialize;
9+
use stack_graphs::graph::NodeID;
10+
use std::collections::HashMap;
11+
use std::path::Path;
12+
13+
use stack_graphs::arena::Handle;
14+
use stack_graphs::graph::File;
15+
use stack_graphs::graph::StackGraph;
16+
use tree_sitter_stack_graphs::FileAnalyzer;
17+
use tree_sitter_stack_graphs::LoadError;
18+
19+
use crate::util::*;
20+
21+
pub struct NpmPackageAnalyzer {}
22+
23+
impl FileAnalyzer for NpmPackageAnalyzer {
24+
fn build_stack_graph_into<'a>(
25+
&self,
26+
graph: &mut StackGraph,
27+
file: Handle<File>,
28+
_path: &Path,
29+
source: &str,
30+
_all_paths: &mut dyn Iterator<Item = &'a Path>,
31+
globals: &HashMap<String, String>,
32+
_cancellation_flag: &dyn tree_sitter_stack_graphs::CancellationFlag,
33+
) -> Result<(), tree_sitter_stack_graphs::LoadError> {
34+
// read globals
35+
let proj_name = globals
36+
.get(crate::PROJECT_NAME_VAR)
37+
.map(String::as_str)
38+
.unwrap_or("");
39+
40+
// parse source
41+
let npm_pkg: NpmPackage =
42+
serde_json::from_str(source).map_err(|_| LoadError::ParseError)?;
43+
44+
// root node
45+
let root = graph.node_for_id(NodeID::root()).unwrap();
46+
47+
// project scope
48+
let proj_scope_id = graph.new_node_id(file);
49+
let proj_scope = graph.add_scope_node(proj_scope_id, false).unwrap();
50+
add_debug_name(graph, proj_scope, "npm_package.proj_scope");
51+
52+
// project definition
53+
let proj_def = add_ns_pop(graph, file, root, PROJ_NS, proj_name);
54+
add_debug_name(graph, proj_def, "npm_package.proj_def");
55+
add_edge(graph, proj_def, proj_scope, 0);
56+
57+
// project reference
58+
let proj_ref = add_ns_push(graph, file, root, PROJ_NS, proj_name);
59+
add_debug_name(graph, proj_ref, "npm_package.proj_ref");
60+
add_edge(graph, proj_scope, proj_ref, 0);
61+
62+
// package definition
63+
let pkg_def = add_module_pops(graph, file, NON_REL_M_NS, Path::new(&npm_pkg.name), root);
64+
add_debug_name(graph, pkg_def, "npm_package.pkg_def");
65+
let pkg_ref = add_push(graph, file, proj_scope, PKG_M_NS);
66+
add_debug_name(graph, pkg_ref, "npm_package.pkg_ref");
67+
add_edge(graph, pkg_def, pkg_ref, 0);
68+
69+
Ok(())
70+
}
71+
}
72+
73+
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
74+
#[serde(rename_all = "camelCase")]
75+
pub struct NpmPackage {
76+
pub name: String,
77+
}

languages/tree-sitter-stack-graphs-typescript/rust/tsconfig.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl FileAnalyzer for TsConfigAnalyzer {
3535
) -> Result<(), tree_sitter_stack_graphs::LoadError> {
3636
// read globals
3737
let proj_name = globals
38-
.get("PROJECT_NAME")
38+
.get(crate::PROJECT_NAME_VAR)
3939
.map(String::as_str)
4040
.unwrap_or("");
4141

@@ -48,41 +48,49 @@ impl FileAnalyzer for TsConfigAnalyzer {
4848
// project scope
4949
let proj_scope_id = graph.new_node_id(file);
5050
let proj_scope = graph.add_scope_node(proj_scope_id, false).unwrap();
51-
add_debug_name(graph, proj_scope, "proj_scope");
51+
add_debug_name(graph, proj_scope, "tsconfig.proj_scope");
5252

5353
// project definition
5454
let proj_def = add_ns_pop(graph, file, root, PROJ_NS, proj_name);
55-
add_debug_name(graph, proj_def, "proj_def");
55+
add_debug_name(graph, proj_def, "tsconfig.proj_def");
5656
add_edge(graph, proj_def, proj_scope, 0);
5757

5858
// project reference
5959
let proj_ref = add_ns_push(graph, file, root, PROJ_NS, proj_name);
60-
add_debug_name(graph, proj_ref, "proj_ref");
60+
add_debug_name(graph, proj_ref, "tsconfig.proj_ref");
6161
add_edge(graph, proj_scope, proj_ref, 0);
6262

6363
// root directory
6464
let pkg_def = add_pop(graph, file, proj_scope, PKG_M_NS);
65-
add_debug_name(graph, pkg_def, "pkg_def");
65+
add_debug_name(graph, pkg_def, "tsconfig.pkg_def");
6666
let root_dir_ref =
6767
add_module_pushes(graph, file, M_NS, &tsc.root_dir(all_paths), proj_scope);
68-
add_debug_name(graph, root_dir_ref, "root_dir.ref");
68+
add_debug_name(graph, root_dir_ref, "tsconfig.root_dir.ref");
6969
add_edge(graph, pkg_def, root_dir_ref, 0);
7070

7171
// auxiliary root directories, map relative imports to module paths
7272
for (idx, root_dir) in tsc.root_dirs().iter().enumerate() {
7373
let root_dir_def = add_pop(graph, file, proj_scope, REL_M_NS);
74-
add_debug_name(graph, root_dir_def, &format!("root_dirs[{}].def", idx));
74+
add_debug_name(
75+
graph,
76+
root_dir_def,
77+
&format!("tsconfig.root_dirs[{}].def", idx),
78+
);
7579
let root_dir_ref = add_module_pushes(graph, file, M_NS, root_dir, proj_scope);
76-
add_debug_name(graph, root_dir_ref, &format!("root_dirs[{}].ref", idx));
80+
add_debug_name(
81+
graph,
82+
root_dir_ref,
83+
&format!("tsconfig.root_dirs[{}].ref", idx),
84+
);
7785
add_edge(graph, root_dir_def, root_dir_ref, 0);
7886
}
7987

8088
// base URL
8189
let base_url = tsc.base_url();
8290
let base_url_def = add_pop(graph, file, proj_scope, NON_REL_M_NS);
83-
add_debug_name(graph, base_url_def, "base_url.def");
91+
add_debug_name(graph, base_url_def, "tsconfig.base_url.def");
8492
let base_url_ref = add_module_pushes(graph, file, M_NS, &base_url, proj_scope);
85-
add_debug_name(graph, base_url_ref, "base_url.ref");
93+
add_debug_name(graph, base_url_ref, "tsconfig.base_url.ref");
8694
add_edge(graph, base_url_def, base_url_ref, 0);
8795

8896
// path mappings
@@ -94,14 +102,18 @@ impl FileAnalyzer for TsConfigAnalyzer {
94102
&from
95103
};
96104
let from_def = add_module_pops(graph, file, NON_REL_M_NS, from, proj_scope);
97-
add_debug_name(graph, from_def, &format!("paths[{}].from_def", from_idx));
105+
add_debug_name(
106+
graph,
107+
from_def,
108+
&format!("tsconfig.paths[{}].from_def", from_idx),
109+
);
98110
for (to_idx, to) in tos.iter().enumerate() {
99111
let to = if is_prefix { to.parent().unwrap() } else { &to };
100112
let to_ref = add_module_pushes(graph, file, M_NS, to, proj_scope);
101113
add_debug_name(
102114
graph,
103115
to_ref,
104-
&format!("paths[{}][{}].to_ref", from_idx, to_idx),
116+
&format!("tsconfig.paths[{}][{}].to_ref", from_idx, to_idx),
105117
);
106118
add_edge(graph, from_def, to_ref, 0);
107119
}

languages/tree-sitter-stack-graphs-typescript/rust/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub const PKG_M_NS: &str = "%PkgM";
2121

2222
pub fn add_debug_name(graph: &mut StackGraph, node: Handle<Node>, name: &str) {
2323
let key = graph.add_string("name");
24-
let value = graph.add_string(&["tsconfig", name].join("."));
24+
let value = graph.add_string(name);
2525
graph.debug_info_mut(node).add(key, value);
2626
}
2727

languages/tree-sitter-stack-graphs-typescript/src/stack-graphs.tsg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n
190190
; proj_scope -> ↑"%PkgM" -> ↓"src" -> ↓"%M"
191191
;
192192
; The various references and definitions for `tsconfig.json` are not created by this TSG file, but
193-
; by the `TsConfigAnalyzer` defined in `rust/tsconfig.rs`.
193+
; by the `TsConfigAnalyzer` defined in `rust/tsconfig.rs`. The global package definition is created
194+
; by the `NpmPackageAnalyzer` in `rust/npm_package.rs`.
194195

195196

196197

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* --- path: ./package.json --- */
2+
{
3+
"name": "@my/pkg"
4+
}
5+
6+
/* --- path: ./tsconfig.json --- */
7+
{
8+
}
9+
10+
/* --- path: ./src/foo.ts --- */
11+
export const bar = 42;
12+
13+
/* --- path: ./src/index.ts --- */
14+
import { bar } from "@my/pkg/foo";
15+
// ^ defined: 11

0 commit comments

Comments
 (0)