ucn 3.1.8 → 3.3.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.
Potentially problematic release.
This version of ucn might be problematic. Click here for more details.
- package/.claude/skills/ucn/SKILL.md +113 -48
- package/README.md +159 -29
- package/cli/index.js +147 -137
- package/core/discovery.js +1 -2
- package/core/imports.js +157 -331
- package/core/output.js +129 -147
- package/core/project.js +484 -220
- package/languages/go.js +21 -10
- package/languages/java.js +25 -9
- package/languages/javascript.js +56 -37
- package/languages/python.js +39 -10
- package/languages/rust.js +36 -8
- package/package.json +1 -1
- package/test/parser.test.js +967 -7
- package/test/reliability-test-prompt.md +58 -0
package/languages/rust.js
CHANGED
|
@@ -11,7 +11,11 @@ const {
|
|
|
11
11
|
parseStructuredParams,
|
|
12
12
|
extractRustDocstring
|
|
13
13
|
} = require('./utils');
|
|
14
|
-
const { PARSE_OPTIONS } = require('./index');
|
|
14
|
+
const { PARSE_OPTIONS, safeParse } = require('./index');
|
|
15
|
+
|
|
16
|
+
function parseTree(parser, code) {
|
|
17
|
+
return safeParse(parser, code, undefined, PARSE_OPTIONS);
|
|
18
|
+
}
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Extract return type from Rust function
|
|
@@ -88,7 +92,7 @@ function extractAttributes(node, code) {
|
|
|
88
92
|
* Find all functions in Rust code using tree-sitter
|
|
89
93
|
*/
|
|
90
94
|
function findFunctions(code, parser) {
|
|
91
|
-
const tree = parser
|
|
95
|
+
const tree = parseTree(parser, code);
|
|
92
96
|
const functions = [];
|
|
93
97
|
const processedRanges = new Set();
|
|
94
98
|
|
|
@@ -177,7 +181,7 @@ function extractGenerics(node) {
|
|
|
177
181
|
* Find all types (structs, enums, traits, impls) in Rust code
|
|
178
182
|
*/
|
|
179
183
|
function findClasses(code, parser) {
|
|
180
|
-
const tree = parser
|
|
184
|
+
const tree = parseTree(parser, code);
|
|
181
185
|
const types = [];
|
|
182
186
|
const processedRanges = new Set();
|
|
183
187
|
|
|
@@ -492,7 +496,7 @@ function extractImplMembers(implNode, code, typeName) {
|
|
|
492
496
|
* Find state objects (const/static) in Rust code
|
|
493
497
|
*/
|
|
494
498
|
function findStateObjects(code, parser) {
|
|
495
|
-
const tree = parser
|
|
499
|
+
const tree = parseTree(parser, code);
|
|
496
500
|
const objects = [];
|
|
497
501
|
|
|
498
502
|
const statePattern = /^([A-Z][A-Z0-9_]+|DEFAULT_[A-Z_]+)$/;
|
|
@@ -555,7 +559,7 @@ function parse(code, parser) {
|
|
|
555
559
|
* @returns {Array<{name: string, line: number, isMethod: boolean, receiver?: string, isMacro?: boolean}>}
|
|
556
560
|
*/
|
|
557
561
|
function findCallsInCode(code, parser) {
|
|
558
|
-
const tree = parser
|
|
562
|
+
const tree = parseTree(parser, code);
|
|
559
563
|
const calls = [];
|
|
560
564
|
const functionStack = []; // Stack of { name, startLine, endLine }
|
|
561
565
|
|
|
@@ -679,7 +683,7 @@ function findCallsInCode(code, parser) {
|
|
|
679
683
|
* @returns {Array<{module: string, names: string[], type: string, line: number}>}
|
|
680
684
|
*/
|
|
681
685
|
function findImportsInCode(code, parser) {
|
|
682
|
-
const tree = parser
|
|
686
|
+
const tree = parseTree(parser, code);
|
|
683
687
|
const imports = [];
|
|
684
688
|
|
|
685
689
|
traverseTree(tree.rootNode, (node) => {
|
|
@@ -698,6 +702,7 @@ function findImportsInCode(code, parser) {
|
|
|
698
702
|
module: path,
|
|
699
703
|
names: [segments[segments.length - 1]],
|
|
700
704
|
type: 'use',
|
|
705
|
+
dynamic: false,
|
|
701
706
|
line
|
|
702
707
|
});
|
|
703
708
|
} else if (child.type === 'use_wildcard') {
|
|
@@ -708,6 +713,7 @@ function findImportsInCode(code, parser) {
|
|
|
708
713
|
module: scopedId.text,
|
|
709
714
|
names: ['*'],
|
|
710
715
|
type: 'use-glob',
|
|
716
|
+
dynamic: true,
|
|
711
717
|
line
|
|
712
718
|
});
|
|
713
719
|
}
|
|
@@ -733,6 +739,7 @@ function findImportsInCode(code, parser) {
|
|
|
733
739
|
module: basePath,
|
|
734
740
|
names,
|
|
735
741
|
type: 'use',
|
|
742
|
+
dynamic: false,
|
|
736
743
|
line
|
|
737
744
|
});
|
|
738
745
|
}
|
|
@@ -754,6 +761,7 @@ function findImportsInCode(code, parser) {
|
|
|
754
761
|
module: nameNode.text,
|
|
755
762
|
names: [nameNode.text],
|
|
756
763
|
type: 'mod',
|
|
764
|
+
dynamic: false,
|
|
757
765
|
line
|
|
758
766
|
});
|
|
759
767
|
}
|
|
@@ -763,6 +771,26 @@ function findImportsInCode(code, parser) {
|
|
|
763
771
|
return true;
|
|
764
772
|
});
|
|
765
773
|
|
|
774
|
+
// include! macros with non-literal paths
|
|
775
|
+
traverseTree(tree.rootNode, (node) => {
|
|
776
|
+
if (node.type === 'macro_invocation') {
|
|
777
|
+
const nameNode = node.childForFieldName('macro');
|
|
778
|
+
if (nameNode && /^include(_str|_bytes)?!$/.test(nameNode.text)) {
|
|
779
|
+
const argsNode = node.childForFieldName('argument_list');
|
|
780
|
+
const arg = argsNode?.namedChild(0);
|
|
781
|
+
const dynamic = !arg || arg.type !== 'string_literal';
|
|
782
|
+
imports.push({
|
|
783
|
+
module: arg ? arg.text.replace(/^["']|["']$/g, '') : null,
|
|
784
|
+
names: [],
|
|
785
|
+
type: 'include',
|
|
786
|
+
dynamic,
|
|
787
|
+
line: node.startPosition.row + 1
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return true;
|
|
792
|
+
});
|
|
793
|
+
|
|
766
794
|
return imports;
|
|
767
795
|
}
|
|
768
796
|
|
|
@@ -774,7 +802,7 @@ function findImportsInCode(code, parser) {
|
|
|
774
802
|
* @returns {Array<{name: string, type: string, line: number}>}
|
|
775
803
|
*/
|
|
776
804
|
function findExportsInCode(code, parser) {
|
|
777
|
-
const tree = parser
|
|
805
|
+
const tree = parseTree(parser, code);
|
|
778
806
|
const exports = [];
|
|
779
807
|
|
|
780
808
|
function hasVisibility(node) {
|
|
@@ -906,7 +934,7 @@ function findExportsInCode(code, parser) {
|
|
|
906
934
|
* @returns {Array<{line: number, column: number, usageType: string}>}
|
|
907
935
|
*/
|
|
908
936
|
function findUsagesInCode(code, name, parser) {
|
|
909
|
-
const tree = parser
|
|
937
|
+
const tree = parseTree(parser, code);
|
|
910
938
|
const usages = [];
|
|
911
939
|
|
|
912
940
|
traverseTree(tree.rootNode, (node) => {
|