code-gauge 4.8.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -9
- package/THIRD-PARTY-NOTICES.txt +1152 -798
- package/dist/cli.cjs +3 -3
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/cliConfig.cjs +1 -1
- package/dist/cliConfig.cjs.map +1 -1
- package/dist/cliConfig.d.ts +13 -3
- package/dist/cliConfig.js +1 -1
- package/dist/cliConfig.js.map +1 -1
- package/dist/diffCommand.cjs +3 -3
- package/dist/diffCommand.cjs.map +1 -1
- package/dist/diffCommand.js +3 -3
- package/dist/diffCommand.js.map +1 -1
- package/dist/duplication.cjs +1 -1
- package/dist/duplication.cjs.map +1 -1
- package/dist/duplication.js +1 -1
- package/dist/duplication.js.map +1 -1
- package/dist/exclusion.cjs +2 -0
- package/dist/exclusion.cjs.map +1 -0
- package/dist/exclusion.d.ts +30 -0
- package/dist/exclusion.js +2 -0
- package/dist/exclusion.js.map +1 -0
- package/dist/git.cjs +1 -1
- package/dist/git.cjs.map +1 -1
- package/dist/git.d.ts +16 -0
- package/dist/git.js +1 -1
- package/dist/git.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/nativeMetrics.cjs +3 -3
- package/dist/nativeMetrics.cjs.map +1 -1
- package/dist/nativeMetrics.js +3 -3
- package/dist/nativeMetrics.js.map +1 -1
- package/dist/newDuplication.cjs +2 -0
- package/dist/newDuplication.cjs.map +1 -0
- package/dist/newDuplication.d.ts +40 -0
- package/dist/newDuplication.js +2 -0
- package/dist/newDuplication.js.map +1 -0
- package/dist/regressionGate.cjs +1 -1
- package/dist/regressionGate.cjs.map +1 -1
- package/dist/regressionGate.d.ts +8 -6
- package/dist/regressionGate.js +1 -1
- package/dist/regressionGate.js.map +1 -1
- package/dist/scan.cjs +1 -1
- package/dist/scan.cjs.map +1 -1
- package/dist/scan.d.ts +12 -4
- package/dist/scan.js +1 -1
- package/dist/scan.js.map +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/native/Cargo.lock +73 -73
- package/native/Cargo.toml +16 -21
- package/native/code-gauge.wasm +0 -0
- package/native/src/dep_degree.rs +6 -6
- package/native/src/duplication.rs +143 -14
- package/native/src/functions.rs +10 -7
- package/native/src/languages.rs +14 -13
- package/native/src/measure.rs +16 -8
- package/native/src/tree_index.rs +4 -4
- package/native/src/util.rs +9 -2
- package/package.json +9 -8
package/native/src/languages.rs
CHANGED
|
@@ -41,24 +41,24 @@ const GRAMMAR_COUNT: usize = GrammarId::Tsx as usize + 1;
|
|
|
41
41
|
impl LanguageDefinition {
|
|
42
42
|
pub fn grammar(&self) -> Language {
|
|
43
43
|
match self.grammar_id {
|
|
44
|
-
GrammarId::C => tree_sitter_c::
|
|
45
|
-
GrammarId::Cpp => tree_sitter_cpp::
|
|
46
|
-
GrammarId::CSharp => tree_sitter_c_sharp::
|
|
47
|
-
GrammarId::Go => tree_sitter_go::
|
|
48
|
-
GrammarId::Java => tree_sitter_java::
|
|
44
|
+
GrammarId::C => tree_sitter_c::LANGUAGE.into(),
|
|
45
|
+
GrammarId::Cpp => tree_sitter_cpp::LANGUAGE.into(),
|
|
46
|
+
GrammarId::CSharp => tree_sitter_c_sharp::LANGUAGE.into(),
|
|
47
|
+
GrammarId::Go => tree_sitter_go::LANGUAGE.into(),
|
|
48
|
+
GrammarId::Java => tree_sitter_java::LANGUAGE.into(),
|
|
49
49
|
GrammarId::JavaScript => tree_sitter_javascript::LANGUAGE.into(),
|
|
50
50
|
GrammarId::Kotlin => tree_sitter_kotlin::LANGUAGE.into(),
|
|
51
|
-
GrammarId::Python => tree_sitter_python::
|
|
52
|
-
GrammarId::Ruby => tree_sitter_ruby::
|
|
53
|
-
GrammarId::Rust => tree_sitter_rust::
|
|
54
|
-
GrammarId::TypeScript => tree_sitter_typescript::
|
|
55
|
-
GrammarId::Tsx => tree_sitter_typescript::
|
|
51
|
+
GrammarId::Python => tree_sitter_python::LANGUAGE.into(),
|
|
52
|
+
GrammarId::Ruby => tree_sitter_ruby::LANGUAGE.into(),
|
|
53
|
+
GrammarId::Rust => tree_sitter_rust::LANGUAGE.into(),
|
|
54
|
+
GrammarId::TypeScript => tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(),
|
|
55
|
+
GrammarId::Tsx => tree_sitter_typescript::LANGUAGE_TSX.into(),
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/// The grammar's node kind names, indexed by kind id.
|
|
60
|
-
pub fn kind_names(&self) -> &'static [
|
|
61
|
-
static KIND_NAMES: [OnceLock<Vec
|
|
60
|
+
pub fn kind_names(&self) -> &'static [String] {
|
|
61
|
+
static KIND_NAMES: [OnceLock<Vec<String>>; GRAMMAR_COUNT] =
|
|
62
62
|
[const { OnceLock::new() }; GRAMMAR_COUNT];
|
|
63
63
|
KIND_NAMES[self.grammar_id as usize].get_or_init(|| {
|
|
64
64
|
let grammar = self.grammar();
|
|
@@ -68,6 +68,7 @@ impl LanguageDefinition {
|
|
|
68
68
|
.ok()
|
|
69
69
|
.and_then(|id| grammar.node_kind_for_id(id))
|
|
70
70
|
.unwrap_or_default()
|
|
71
|
+
.to_string()
|
|
71
72
|
})
|
|
72
73
|
.collect()
|
|
73
74
|
})
|
|
@@ -361,7 +362,6 @@ const PYTHON_NCSS_NODES: &[&str] = &[
|
|
|
361
362
|
"for_statement",
|
|
362
363
|
"while_statement",
|
|
363
364
|
"except_clause",
|
|
364
|
-
"except_group_clause",
|
|
365
365
|
"finally_clause",
|
|
366
366
|
"with_statement",
|
|
367
367
|
"match_statement",
|
|
@@ -595,6 +595,7 @@ const CSHARP_NCSS_NODES: &[&str] = &[
|
|
|
595
595
|
"interface_declaration",
|
|
596
596
|
"enum_declaration",
|
|
597
597
|
"record_declaration",
|
|
598
|
+
"extension_declaration",
|
|
598
599
|
"delegate_declaration",
|
|
599
600
|
"field_declaration",
|
|
600
601
|
"event_field_declaration",
|
package/native/src/measure.rs
CHANGED
|
@@ -16,7 +16,9 @@ use crate::tree_index::{NodeExt, TreeIndex};
|
|
|
16
16
|
use crate::types::{
|
|
17
17
|
CrossFileFileData, FunctionMetrics, HalsteadCounts, LineMetrics, NativeMetrics,
|
|
18
18
|
};
|
|
19
|
-
use crate::util::{
|
|
19
|
+
use crate::util::{
|
|
20
|
+
all_children, is_js_whitespace, is_token, named_children, node_text, split_lines, Source,
|
|
21
|
+
};
|
|
20
22
|
|
|
21
23
|
pub fn measure(
|
|
22
24
|
code: &str,
|
|
@@ -274,11 +276,11 @@ fn collect_token_symbols(
|
|
|
274
276
|
) {
|
|
275
277
|
return;
|
|
276
278
|
}
|
|
277
|
-
if
|
|
279
|
+
if is_atomic_operand(node) {
|
|
278
280
|
symbols.push(hash_text(node.kind_name()));
|
|
279
281
|
return;
|
|
280
282
|
}
|
|
281
|
-
if node
|
|
283
|
+
if !is_token(node) {
|
|
282
284
|
for child in all_children(node) {
|
|
283
285
|
collect_token_symbols(child, code, symbols, id_index_by_name);
|
|
284
286
|
}
|
|
@@ -584,8 +586,6 @@ const OPERAND_NODE_TYPES: &[&str] = &[
|
|
|
584
586
|
"hex_floating_point_literal",
|
|
585
587
|
"string",
|
|
586
588
|
"string_literal",
|
|
587
|
-
// Go raw strings are leaves with no content child, unlike Rust/C++ `raw_string_literal`s.
|
|
588
|
-
"raw_string_literal",
|
|
589
589
|
"verbatim_string_literal",
|
|
590
590
|
"string_fragment",
|
|
591
591
|
"multiline_string_fragment",
|
|
@@ -638,7 +638,7 @@ fn measure_halstead(root: Node<'_>, code: &Source<'_>) -> HalsteadCounts {
|
|
|
638
638
|
let mut operands: FxHashMap<&str, u64> = FxHashMap::default();
|
|
639
639
|
|
|
640
640
|
fn visit<'a>(
|
|
641
|
-
node: Node<'
|
|
641
|
+
node: Node<'a>,
|
|
642
642
|
code: &Source<'a>,
|
|
643
643
|
operators: &mut FxHashMap<&'a str, u64>,
|
|
644
644
|
operands: &mut FxHashMap<&'a str, u64>,
|
|
@@ -650,14 +650,14 @@ fn measure_halstead(root: Node<'_>, code: &Source<'_>) -> HalsteadCounts {
|
|
|
650
650
|
return;
|
|
651
651
|
}
|
|
652
652
|
|
|
653
|
-
if
|
|
653
|
+
if is_atomic_operand(node) {
|
|
654
654
|
*operands.entry(node_text(node, code)).or_insert(0) += 1;
|
|
655
655
|
return;
|
|
656
656
|
}
|
|
657
657
|
|
|
658
658
|
// Operators are counted from leaf tokens only: keyword-named nodes always contain a
|
|
659
659
|
// same-text anonymous keyword leaf, so counting the named node as well would double-count.
|
|
660
|
-
if node
|
|
660
|
+
if is_token(node) {
|
|
661
661
|
let text = node_text(node, code);
|
|
662
662
|
// Operands win over text matches so identifiers spelled like word operators stay operands;
|
|
663
663
|
// C# `nameof(x)` is the one keyword operator the grammar parses as a plain callee.
|
|
@@ -694,6 +694,14 @@ fn measure_halstead(root: Node<'_>, code: &Source<'_>) -> HalsteadCounts {
|
|
|
694
694
|
}
|
|
695
695
|
}
|
|
696
696
|
|
|
697
|
+
/// A literal counted as one operand without descending: ATOMIC_OPERAND_NODE_TYPES, or a Go raw
|
|
698
|
+
/// string, which wraps its content like Go's interpreted strings (the Rust and C++
|
|
699
|
+
/// `raw_string_literal`s count their content leaves instead).
|
|
700
|
+
fn is_atomic_operand(node: Node<'_>) -> bool {
|
|
701
|
+
atomic_operand_node_types().contains(node.kind_name())
|
|
702
|
+
|| (node.kind_name() == "raw_string_literal" && crate::tree_index::language_name() == "go")
|
|
703
|
+
}
|
|
704
|
+
|
|
697
705
|
/// tree-sitter-c-sharp parses `nameof(x)` as an invocation of an identifier named `nameof`.
|
|
698
706
|
fn is_csharp_nameof_callee(node: Node<'_>, text: &str) -> bool {
|
|
699
707
|
text == "nameof"
|
package/native/src/tree_index.rs
CHANGED
|
@@ -11,7 +11,7 @@ thread_local! {
|
|
|
11
11
|
/// nodes; TreeIndex borrows the tree and clears the map on drop, so no entry outlives it.
|
|
12
12
|
static PARENTS: RefCell<FxHashMap<usize, Node<'static>>> = RefCell::new(FxHashMap::default());
|
|
13
13
|
/// Node kind names of the indexed tree's language, indexed by kind id.
|
|
14
|
-
static KIND_NAMES: Cell<&'static [
|
|
14
|
+
static KIND_NAMES: Cell<&'static [String]> = const { Cell::new(&[]) };
|
|
15
15
|
/// Name of the indexed tree's language.
|
|
16
16
|
static LANGUAGE_NAME: Cell<&'static str> = const { Cell::new("") };
|
|
17
17
|
}
|
|
@@ -87,7 +87,7 @@ pub trait NodeExt<'t> {
|
|
|
87
87
|
/// `Node::parent`, answered from the TreeIndex when one is installed.
|
|
88
88
|
fn parent_node(self) -> Option<Node<'t>>;
|
|
89
89
|
/// `Node::kind`, answered from the TreeIndex when one is installed.
|
|
90
|
-
fn kind_name(self) -> &'
|
|
90
|
+
fn kind_name(self) -> &'t str;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
impl<'t> NodeExt<'t> for Node<'t> {
|
|
@@ -109,11 +109,11 @@ impl<'t> NodeExt<'t> for Node<'t> {
|
|
|
109
109
|
.or_else(|| self.parent())
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
fn kind_name(self) -> &'
|
|
112
|
+
fn kind_name(self) -> &'t str {
|
|
113
113
|
KIND_NAMES
|
|
114
114
|
.get()
|
|
115
115
|
.get(usize::from(self.kind_id()))
|
|
116
|
-
.
|
|
116
|
+
.map(String::as_str)
|
|
117
117
|
.unwrap_or_else(|| self.kind())
|
|
118
118
|
}
|
|
119
119
|
}
|
package/native/src/util.rs
CHANGED
|
@@ -61,6 +61,13 @@ pub fn is_kotlin_keyword_literal(node: Node<'_>, code: &Source<'_>) -> bool {
|
|
|
61
61
|
&& matches!(node_text(node, code), "true" | "false" | "null")
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/// Whether the node stands for one source token. C# spells a contextual keyword used as a name
|
|
65
|
+
/// (`type`, `field`, `alias`) as an `identifier` or `implicit_parameter` wrapping the keyword token,
|
|
66
|
+
/// which still names a variable like any other identifier.
|
|
67
|
+
pub fn is_token(node: Node<'_>) -> bool {
|
|
68
|
+
node.child_count() == 0 || matches!(node.kind_name(), "identifier" | "implicit_parameter")
|
|
69
|
+
}
|
|
70
|
+
|
|
64
71
|
pub fn named_children<'t>(node: Node<'t>) -> Vec<Node<'t>> {
|
|
65
72
|
let mut cursor = node.walk();
|
|
66
73
|
node.named_children(&mut cursor).collect()
|
|
@@ -77,13 +84,13 @@ pub fn all_children<'t>(node: Node<'t>) -> Vec<Node<'t>> {
|
|
|
77
84
|
/// them), which would desynchronize field-based extraction on malformed source.
|
|
78
85
|
pub fn find_children_by_field_name<'t>(node: Node<'t>, field_name: &str) -> Vec<Node<'t>> {
|
|
79
86
|
let mut children = Vec::new();
|
|
80
|
-
let mut preceding_structural_field
|
|
87
|
+
let mut preceding_structural_field = None;
|
|
81
88
|
for index in 0..node.child_count() {
|
|
82
89
|
if let Some(child) = node.child(index) {
|
|
83
90
|
let field = if child.is_extra() {
|
|
84
91
|
preceding_structural_field
|
|
85
92
|
} else {
|
|
86
|
-
let field = node.field_name_for_child(index
|
|
93
|
+
let field = node.field_name_for_child(index);
|
|
87
94
|
preceding_structural_field = field;
|
|
88
95
|
field
|
|
89
96
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-gauge",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Measure code metrics with tree-sitter.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"verify-full": "bun wb verify --full"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
+
"@willbooster/shared-lib": "10.18.0",
|
|
65
66
|
"commander": "15.0.0"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
@@ -94,12 +95,12 @@
|
|
|
94
95
|
"registry": "https://registry.npmjs.org/"
|
|
95
96
|
},
|
|
96
97
|
"optionalDependencies": {
|
|
97
|
-
"code-gauge-linux-x64-gnu": "
|
|
98
|
-
"code-gauge-linux-arm64-gnu": "
|
|
99
|
-
"code-gauge-linux-x64-musl": "
|
|
100
|
-
"code-gauge-linux-arm64-musl": "
|
|
101
|
-
"code-gauge-darwin-x64": "
|
|
102
|
-
"code-gauge-darwin-arm64": "
|
|
103
|
-
"code-gauge-win32-x64-msvc": "
|
|
98
|
+
"code-gauge-linux-x64-gnu": "5.1.0",
|
|
99
|
+
"code-gauge-linux-arm64-gnu": "5.1.0",
|
|
100
|
+
"code-gauge-linux-x64-musl": "5.1.0",
|
|
101
|
+
"code-gauge-linux-arm64-musl": "5.1.0",
|
|
102
|
+
"code-gauge-darwin-x64": "5.1.0",
|
|
103
|
+
"code-gauge-darwin-arm64": "5.1.0",
|
|
104
|
+
"code-gauge-win32-x64-msvc": "5.1.0"
|
|
104
105
|
}
|
|
105
106
|
}
|