|
| 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 std::collections::HashMap; |
| 10 | +use std::path::Path; |
| 11 | + |
| 12 | +use stack_graphs::arena::Handle; |
| 13 | +use stack_graphs::graph::File; |
| 14 | +use stack_graphs::graph::StackGraph; |
| 15 | +use tree_sitter_stack_graphs::FileAnalyzer; |
| 16 | +use tree_sitter_stack_graphs::LoadError; |
| 17 | + |
| 18 | +use crate::util::*; |
| 19 | + |
| 20 | +pub struct NpmPackageAnalyzer {} |
| 21 | + |
| 22 | +impl FileAnalyzer for NpmPackageAnalyzer { |
| 23 | + fn build_stack_graph_into<'a>( |
| 24 | + &self, |
| 25 | + graph: &mut StackGraph, |
| 26 | + file: Handle<File>, |
| 27 | + _path: &Path, |
| 28 | + source: &str, |
| 29 | + _all_paths: &mut dyn Iterator<Item = &'a Path>, |
| 30 | + globals: &HashMap<String, String>, |
| 31 | + _cancellation_flag: &dyn tree_sitter_stack_graphs::CancellationFlag, |
| 32 | + ) -> Result<(), tree_sitter_stack_graphs::LoadError> { |
| 33 | + // read globals |
| 34 | + let proj_name = globals |
| 35 | + .get(crate::PROJECT_NAME_VAR) |
| 36 | + .map(String::as_str) |
| 37 | + .unwrap_or(""); |
| 38 | + |
| 39 | + // parse source |
| 40 | + let npm_pkg: NpmPackage = |
| 41 | + serde_json::from_str(source).map_err(|_| LoadError::ParseError)?; |
| 42 | + |
| 43 | + // root node |
| 44 | + let root = StackGraph::root_node(); |
| 45 | + |
| 46 | + // project scope |
| 47 | + let proj_scope_id = graph.new_node_id(file); |
| 48 | + let proj_scope = graph.add_scope_node(proj_scope_id, false).unwrap(); |
| 49 | + add_debug_name(graph, proj_scope, "npm_package.proj_scope"); |
| 50 | + |
| 51 | + // project definition |
| 52 | + let proj_def = add_ns_pop(graph, file, root, PROJ_NS, proj_name); |
| 53 | + add_debug_name(graph, proj_def, "npm_package.proj_def"); |
| 54 | + add_edge(graph, proj_def, proj_scope, 0); |
| 55 | + |
| 56 | + // project reference |
| 57 | + let proj_ref = add_ns_push(graph, file, root, PROJ_NS, proj_name); |
| 58 | + add_debug_name(graph, proj_ref, "npm_package.proj_ref"); |
| 59 | + add_edge(graph, proj_scope, proj_ref, 0); |
| 60 | + |
| 61 | + // package definition |
| 62 | + let pkg_def = add_module_pops(graph, file, NON_REL_M_NS, Path::new(&npm_pkg.name), root); |
| 63 | + add_debug_name(graph, pkg_def, "npm_package.pkg_def"); |
| 64 | + let pkg_ref = add_push(graph, file, proj_scope, PKG_M_NS); |
| 65 | + add_debug_name(graph, pkg_ref, "npm_package.pkg_ref"); |
| 66 | + add_edge(graph, pkg_def, pkg_ref, 0); |
| 67 | + |
| 68 | + Ok(()) |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +#[derive(Default, Debug, Clone, PartialEq, Deserialize)] |
| 73 | +#[serde(rename_all = "camelCase")] |
| 74 | +pub struct NpmPackage { |
| 75 | + pub name: String, |
| 76 | +} |
0 commit comments