gitnexus 1.4.8 → 1.4.10
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 +7 -0
- package/dist/cli/index-repo.d.ts +15 -0
- package/dist/cli/index-repo.js +115 -0
- package/dist/cli/index.js +11 -2
- package/dist/cli/setup.js +12 -9
- package/dist/cli/wiki.d.ts +4 -0
- package/dist/cli/wiki.js +174 -53
- package/dist/config/supported-languages.d.ts +7 -5
- package/dist/config/supported-languages.js +6 -4
- package/dist/core/graph/graph.js +9 -1
- package/dist/core/graph/types.d.ts +10 -2
- package/dist/core/ingestion/call-processor.d.ts +18 -1
- package/dist/core/ingestion/call-processor.js +297 -38
- package/dist/core/ingestion/call-routing.d.ts +3 -18
- package/dist/core/ingestion/call-routing.js +0 -19
- package/dist/core/ingestion/cobol/cobol-copy-expander.d.ts +57 -0
- package/dist/core/ingestion/cobol/cobol-copy-expander.js +385 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.d.ts +210 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1509 -0
- package/dist/core/ingestion/cobol/jcl-parser.d.ts +68 -0
- package/dist/core/ingestion/cobol/jcl-parser.js +217 -0
- package/dist/core/ingestion/cobol/jcl-processor.d.ts +33 -0
- package/dist/core/ingestion/cobol/jcl-processor.js +229 -0
- package/dist/core/ingestion/cobol-processor.d.ts +54 -0
- package/dist/core/ingestion/cobol-processor.js +1186 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +17 -0
- package/dist/core/ingestion/entry-point-scoring.js +18 -4
- package/dist/core/ingestion/export-detection.d.ts +47 -8
- package/dist/core/ingestion/export-detection.js +29 -50
- package/dist/core/ingestion/field-extractor.d.ts +29 -0
- package/dist/core/ingestion/field-extractor.js +25 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.js +108 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.js +73 -0
- package/dist/core/ingestion/field-extractors/configs/dart.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/dart.js +76 -0
- package/dist/core/ingestion/field-extractors/configs/go.d.ts +11 -0
- package/dist/core/ingestion/field-extractors/configs/go.js +64 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +44 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.js +134 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.js +118 -0
- package/dist/core/ingestion/field-extractors/configs/php.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/php.js +67 -0
- package/dist/core/ingestion/field-extractors/configs/python.d.ts +12 -0
- package/dist/core/ingestion/field-extractors/configs/python.js +91 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.d.ts +16 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.js +75 -0
- package/dist/core/ingestion/field-extractors/configs/rust.d.ts +9 -0
- package/dist/core/ingestion/field-extractors/configs/rust.js +55 -0
- package/dist/core/ingestion/field-extractors/configs/swift.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/swift.js +63 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.js +60 -0
- package/dist/core/ingestion/field-extractors/generic.d.ts +46 -0
- package/dist/core/ingestion/field-extractors/generic.js +111 -0
- package/dist/core/ingestion/field-extractors/typescript.d.ts +77 -0
- package/dist/core/ingestion/field-extractors/typescript.js +291 -0
- package/dist/core/ingestion/field-types.d.ts +59 -0
- package/dist/core/ingestion/field-types.js +2 -0
- package/dist/core/ingestion/framework-detection.d.ts +87 -0
- package/dist/core/ingestion/framework-detection.js +65 -2
- package/dist/core/ingestion/heritage-processor.js +15 -17
- package/dist/core/ingestion/import-processor.d.ts +9 -10
- package/dist/core/ingestion/import-processor.js +59 -14
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.d.ts +6 -9
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.js +20 -2
- package/dist/core/ingestion/import-resolvers/dart.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/dart.js +44 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.d.ts +4 -5
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.js +17 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.d.ts +9 -1
- package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.js +56 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/php.d.ts +6 -10
- package/dist/core/ingestion/{resolvers → import-resolvers}/php.js +7 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.d.ts +9 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.js +35 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.js +7 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.js +41 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.d.ts +15 -7
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.js +22 -3
- package/dist/core/ingestion/import-resolvers/swift.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/swift.js +23 -0
- package/dist/core/ingestion/import-resolvers/types.d.ts +44 -0
- package/dist/core/ingestion/import-resolvers/types.js +6 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.d.ts +0 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.js +0 -9
- package/dist/core/ingestion/language-config.d.ts +4 -1
- package/dist/core/ingestion/language-provider.d.ts +121 -0
- package/dist/core/ingestion/language-provider.js +24 -0
- package/dist/core/ingestion/languages/c-cpp.d.ts +12 -0
- package/dist/core/ingestion/languages/c-cpp.js +71 -0
- package/dist/core/ingestion/languages/cobol.d.ts +1 -0
- package/dist/core/ingestion/languages/cobol.js +26 -0
- package/dist/core/ingestion/languages/csharp.d.ts +8 -0
- package/dist/core/ingestion/languages/csharp.js +49 -0
- package/dist/core/ingestion/languages/dart.d.ts +12 -0
- package/dist/core/ingestion/languages/dart.js +58 -0
- package/dist/core/ingestion/languages/go.d.ts +11 -0
- package/dist/core/ingestion/languages/go.js +28 -0
- package/dist/core/ingestion/languages/index.d.ts +38 -0
- package/dist/core/ingestion/languages/index.js +63 -0
- package/dist/core/ingestion/languages/java.d.ts +9 -0
- package/dist/core/ingestion/languages/java.js +29 -0
- package/dist/core/ingestion/languages/kotlin.d.ts +9 -0
- package/dist/core/ingestion/languages/kotlin.js +53 -0
- package/dist/core/ingestion/languages/php.d.ts +8 -0
- package/dist/core/ingestion/languages/php.js +145 -0
- package/dist/core/ingestion/languages/python.d.ts +12 -0
- package/dist/core/ingestion/languages/python.js +39 -0
- package/dist/core/ingestion/languages/ruby.d.ts +9 -0
- package/dist/core/ingestion/languages/ruby.js +44 -0
- package/dist/core/ingestion/languages/rust.d.ts +12 -0
- package/dist/core/ingestion/languages/rust.js +44 -0
- package/dist/core/ingestion/languages/swift.d.ts +12 -0
- package/dist/core/ingestion/languages/swift.js +133 -0
- package/dist/core/ingestion/languages/typescript.d.ts +10 -0
- package/dist/core/ingestion/languages/typescript.js +60 -0
- package/dist/core/ingestion/mro-processor.js +14 -15
- package/dist/core/ingestion/{named-binding-extraction.d.ts → named-binding-processor.d.ts} +0 -9
- package/dist/core/ingestion/named-binding-processor.js +42 -0
- package/dist/core/ingestion/named-bindings/csharp.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/csharp.js +37 -0
- package/dist/core/ingestion/named-bindings/java.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/java.js +29 -0
- package/dist/core/ingestion/named-bindings/kotlin.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/kotlin.js +36 -0
- package/dist/core/ingestion/named-bindings/php.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/php.js +61 -0
- package/dist/core/ingestion/named-bindings/python.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/python.js +49 -0
- package/dist/core/ingestion/named-bindings/rust.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/rust.js +64 -0
- package/dist/core/ingestion/named-bindings/types.d.ts +16 -0
- package/dist/core/ingestion/named-bindings/types.js +6 -0
- package/dist/core/ingestion/named-bindings/typescript.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/typescript.js +58 -0
- package/dist/core/ingestion/parsing-processor.d.ts +5 -1
- package/dist/core/ingestion/parsing-processor.js +115 -16
- package/dist/core/ingestion/pipeline.js +925 -424
- package/dist/core/ingestion/resolution-context.js +1 -1
- package/dist/core/ingestion/route-extractors/expo.d.ts +1 -0
- package/dist/core/ingestion/route-extractors/expo.js +36 -0
- package/dist/core/ingestion/route-extractors/middleware.d.ts +47 -0
- package/dist/core/ingestion/route-extractors/middleware.js +143 -0
- package/dist/core/ingestion/route-extractors/nextjs.d.ts +3 -0
- package/dist/core/ingestion/route-extractors/nextjs.js +76 -0
- package/dist/core/ingestion/route-extractors/php.d.ts +7 -0
- package/dist/core/ingestion/route-extractors/php.js +21 -0
- package/dist/core/ingestion/route-extractors/response-shapes.d.ts +20 -0
- package/dist/core/ingestion/route-extractors/response-shapes.js +290 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +8 -7
- package/dist/core/ingestion/tree-sitter-queries.js +231 -9
- package/dist/core/ingestion/type-env.d.ts +14 -17
- package/dist/core/ingestion/type-env.js +66 -14
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +1 -1
- package/dist/core/ingestion/type-extractors/csharp.js +1 -1
- package/dist/core/ingestion/type-extractors/dart.d.ts +15 -0
- package/dist/core/ingestion/type-extractors/dart.js +371 -0
- package/dist/core/ingestion/type-extractors/jvm.js +1 -1
- package/dist/core/ingestion/type-extractors/shared.d.ts +1 -13
- package/dist/core/ingestion/type-extractors/shared.js +9 -102
- package/dist/core/ingestion/type-extractors/swift.js +334 -4
- package/dist/core/ingestion/type-extractors/types.d.ts +3 -1
- package/dist/core/ingestion/{ast-helpers.d.ts → utils/ast-helpers.d.ts} +16 -13
- package/dist/core/ingestion/{ast-helpers.js → utils/ast-helpers.js} +111 -32
- package/dist/core/ingestion/{call-analysis.js → utils/call-analysis.js} +37 -0
- package/dist/core/ingestion/utils/event-loop.d.ts +5 -0
- package/dist/core/ingestion/utils/event-loop.js +5 -0
- package/dist/core/ingestion/utils/language-detection.d.ts +9 -0
- package/dist/core/ingestion/utils/language-detection.js +70 -0
- package/dist/core/ingestion/utils/verbose.d.ts +1 -0
- package/dist/core/ingestion/utils/verbose.js +7 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +43 -2
- package/dist/core/ingestion/workers/parse-worker.js +361 -150
- package/dist/core/lbug/csv-generator.js +34 -1
- package/dist/core/lbug/lbug-adapter.js +6 -0
- package/dist/core/lbug/schema.d.ts +5 -3
- package/dist/core/lbug/schema.js +39 -2
- package/dist/core/tree-sitter/parser-loader.js +7 -1
- package/dist/core/wiki/cursor-client.d.ts +31 -0
- package/dist/core/wiki/cursor-client.js +127 -0
- package/dist/core/wiki/generator.d.ts +28 -9
- package/dist/core/wiki/generator.js +115 -18
- package/dist/core/wiki/graph-queries.d.ts +4 -0
- package/dist/core/wiki/graph-queries.js +7 -1
- package/dist/core/wiki/llm-client.d.ts +2 -0
- package/dist/core/wiki/llm-client.js +8 -4
- package/dist/core/wiki/prompts.d.ts +3 -3
- package/dist/core/wiki/prompts.js +6 -0
- package/dist/mcp/core/lbug-adapter.d.ts +5 -0
- package/dist/mcp/core/lbug-adapter.js +11 -1
- package/dist/mcp/local/local-backend.d.ts +16 -5
- package/dist/mcp/local/local-backend.js +711 -74
- package/dist/mcp/tools.js +71 -2
- package/dist/storage/repo-manager.d.ts +3 -0
- package/package.json +14 -14
- package/dist/core/ingestion/import-resolution.d.ts +0 -101
- package/dist/core/ingestion/import-resolution.js +0 -251
- package/dist/core/ingestion/named-binding-extraction.js +0 -373
- package/dist/core/ingestion/resolvers/index.d.ts +0 -18
- package/dist/core/ingestion/resolvers/index.js +0 -13
- package/dist/core/ingestion/type-extractors/index.d.ts +0 -22
- package/dist/core/ingestion/type-extractors/index.js +0 -31
- package/dist/core/ingestion/utils.d.ts +0 -20
- package/dist/core/ingestion/utils.js +0 -242
- package/scripts/patch-tree-sitter-swift.cjs +0 -74
- /package/dist/core/ingestion/{call-analysis.d.ts → utils/call-analysis.d.ts} +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractors/configs/rust.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../config/supported-languages.js';
|
|
3
|
+
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
4
|
+
import { hasKeyword } from './helpers.js';
|
|
5
|
+
/**
|
|
6
|
+
* Rust field extraction config.
|
|
7
|
+
*
|
|
8
|
+
* Handles struct fields (named and tuple variants are out of scope).
|
|
9
|
+
* Visibility: `pub` keyword = public, otherwise private (crate-private).
|
|
10
|
+
* All fields are immutable by default in Rust (mutability is on the binding).
|
|
11
|
+
*/
|
|
12
|
+
export const rustConfig = {
|
|
13
|
+
language: SupportedLanguages.Rust,
|
|
14
|
+
typeDeclarationNodes: [
|
|
15
|
+
'struct_item',
|
|
16
|
+
'enum_item',
|
|
17
|
+
],
|
|
18
|
+
fieldNodeTypes: ['field_declaration'],
|
|
19
|
+
bodyNodeTypes: ['field_declaration_list'],
|
|
20
|
+
defaultVisibility: 'private',
|
|
21
|
+
extractName(node) {
|
|
22
|
+
const name = node.childForFieldName('name');
|
|
23
|
+
if (name)
|
|
24
|
+
return name.text;
|
|
25
|
+
// fallback: first field_identifier
|
|
26
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
27
|
+
const child = node.namedChild(i);
|
|
28
|
+
if (child?.type === 'field_identifier')
|
|
29
|
+
return child.text;
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
},
|
|
33
|
+
extractType(node) {
|
|
34
|
+
const typeNode = node.childForFieldName('type');
|
|
35
|
+
if (typeNode)
|
|
36
|
+
return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
|
|
37
|
+
return undefined;
|
|
38
|
+
},
|
|
39
|
+
extractVisibility(node) {
|
|
40
|
+
// Check for visibility_modifier named child (pub, pub(crate), pub(super))
|
|
41
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
42
|
+
const child = node.namedChild(i);
|
|
43
|
+
if (child?.type === 'visibility_modifier')
|
|
44
|
+
return 'public';
|
|
45
|
+
}
|
|
46
|
+
return hasKeyword(node, 'pub') ? 'public' : 'private';
|
|
47
|
+
},
|
|
48
|
+
isStatic(_node) {
|
|
49
|
+
return false; // Rust struct fields are never static
|
|
50
|
+
},
|
|
51
|
+
isReadonly(_node) {
|
|
52
|
+
// All Rust fields are immutable by default (mutability is per-binding)
|
|
53
|
+
return true;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FieldExtractionConfig } from '../generic.js';
|
|
2
|
+
/**
|
|
3
|
+
* Swift field extraction config.
|
|
4
|
+
*
|
|
5
|
+
* Handles property_declaration inside class_body / protocol_body.
|
|
6
|
+
* tree-sitter-swift uses property_declaration for stored/computed properties.
|
|
7
|
+
*/
|
|
8
|
+
export declare const swiftConfig: FieldExtractionConfig;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractors/configs/swift.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../config/supported-languages.js';
|
|
3
|
+
import { hasKeyword, findVisibility } from './helpers.js';
|
|
4
|
+
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
5
|
+
const SWIFT_VIS = new Set(['public', 'private', 'fileprivate', 'internal', 'open']);
|
|
6
|
+
/**
|
|
7
|
+
* Swift field extraction config.
|
|
8
|
+
*
|
|
9
|
+
* Handles property_declaration inside class_body / protocol_body.
|
|
10
|
+
* tree-sitter-swift uses property_declaration for stored/computed properties.
|
|
11
|
+
*/
|
|
12
|
+
export const swiftConfig = {
|
|
13
|
+
language: SupportedLanguages.Swift,
|
|
14
|
+
typeDeclarationNodes: [
|
|
15
|
+
'class_declaration',
|
|
16
|
+
'struct_declaration',
|
|
17
|
+
'protocol_declaration',
|
|
18
|
+
],
|
|
19
|
+
fieldNodeTypes: ['property_declaration'],
|
|
20
|
+
bodyNodeTypes: ['class_body', 'protocol_body'],
|
|
21
|
+
defaultVisibility: 'internal',
|
|
22
|
+
extractName(node) {
|
|
23
|
+
// property_declaration > pattern > simple_identifier
|
|
24
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
25
|
+
const child = node.namedChild(i);
|
|
26
|
+
if (child?.type === 'pattern') {
|
|
27
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
28
|
+
const ident = child.namedChild(j);
|
|
29
|
+
if (ident?.type === 'simple_identifier')
|
|
30
|
+
return ident.text;
|
|
31
|
+
}
|
|
32
|
+
return child.text;
|
|
33
|
+
}
|
|
34
|
+
if (child?.type === 'simple_identifier')
|
|
35
|
+
return child.text;
|
|
36
|
+
}
|
|
37
|
+
// fallback: childForFieldName('name')
|
|
38
|
+
const name = node.childForFieldName('name');
|
|
39
|
+
return name?.text;
|
|
40
|
+
},
|
|
41
|
+
extractType(node) {
|
|
42
|
+
// property_declaration > type_annotation > type_identifier
|
|
43
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
44
|
+
const child = node.namedChild(i);
|
|
45
|
+
if (child?.type === 'type_annotation') {
|
|
46
|
+
const inner = child.firstNamedChild;
|
|
47
|
+
if (inner)
|
|
48
|
+
return extractSimpleTypeName(inner) ?? inner.text?.trim();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
},
|
|
53
|
+
extractVisibility(node) {
|
|
54
|
+
return findVisibility(node, SWIFT_VIS, 'internal', 'modifiers');
|
|
55
|
+
},
|
|
56
|
+
isStatic(node) {
|
|
57
|
+
return hasKeyword(node, 'static') || hasKeyword(node, 'class');
|
|
58
|
+
},
|
|
59
|
+
isReadonly(node) {
|
|
60
|
+
// 'let' = constant/readonly, 'var' = variable
|
|
61
|
+
return hasKeyword(node, 'let');
|
|
62
|
+
},
|
|
63
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractors/configs/typescript-javascript.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../config/supported-languages.js';
|
|
3
|
+
import { hasKeyword, findVisibility, typeFromAnnotation } from './helpers.js';
|
|
4
|
+
const VISIBILITY_KEYWORDS = new Set(['public', 'private', 'protected']);
|
|
5
|
+
const shared = {
|
|
6
|
+
typeDeclarationNodes: [
|
|
7
|
+
'class_declaration',
|
|
8
|
+
'abstract_class_declaration',
|
|
9
|
+
'interface_declaration',
|
|
10
|
+
],
|
|
11
|
+
fieldNodeTypes: [
|
|
12
|
+
'public_field_definition',
|
|
13
|
+
'property_signature',
|
|
14
|
+
'field_definition',
|
|
15
|
+
],
|
|
16
|
+
bodyNodeTypes: ['class_body', 'interface_body', 'object_type'],
|
|
17
|
+
defaultVisibility: 'public',
|
|
18
|
+
extractName(node) {
|
|
19
|
+
const nameNode = node.childForFieldName('name') ?? node.childForFieldName('property');
|
|
20
|
+
return nameNode?.text;
|
|
21
|
+
},
|
|
22
|
+
extractType(node) {
|
|
23
|
+
// tree-sitter TS uses a named 'type' field for type_annotation
|
|
24
|
+
const typeField = node.childForFieldName('type');
|
|
25
|
+
if (typeField) {
|
|
26
|
+
if (typeField.type === 'type_annotation') {
|
|
27
|
+
const inner = typeField.firstNamedChild;
|
|
28
|
+
return inner?.text?.trim();
|
|
29
|
+
}
|
|
30
|
+
return typeField.text?.trim();
|
|
31
|
+
}
|
|
32
|
+
return typeFromAnnotation(node);
|
|
33
|
+
},
|
|
34
|
+
extractVisibility(node) {
|
|
35
|
+
// TypeScript accessibility_modifier
|
|
36
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
37
|
+
const child = node.namedChild(i);
|
|
38
|
+
if (child && child.type === 'accessibility_modifier') {
|
|
39
|
+
const t = child.text.trim();
|
|
40
|
+
if (VISIBILITY_KEYWORDS.has(t))
|
|
41
|
+
return t;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return findVisibility(node, VISIBILITY_KEYWORDS, 'public', 'modifiers');
|
|
45
|
+
},
|
|
46
|
+
isStatic(node) {
|
|
47
|
+
return hasKeyword(node, 'static');
|
|
48
|
+
},
|
|
49
|
+
isReadonly(node) {
|
|
50
|
+
return hasKeyword(node, 'readonly');
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export const typescriptConfig = {
|
|
54
|
+
...shared,
|
|
55
|
+
language: SupportedLanguages.TypeScript,
|
|
56
|
+
};
|
|
57
|
+
export const javascriptConfig = {
|
|
58
|
+
...shared,
|
|
59
|
+
language: SupportedLanguages.JavaScript,
|
|
60
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic table-driven field extractor factory.
|
|
3
|
+
*
|
|
4
|
+
* Instead of 14 separate 300-line files, define a config per language and
|
|
5
|
+
* generate extractors from configs. The factory creates a class extending
|
|
6
|
+
* BaseFieldExtractor whose behaviour is entirely driven by FieldExtractionConfig.
|
|
7
|
+
*/
|
|
8
|
+
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
|
9
|
+
import { SupportedLanguages } from '../../../config/supported-languages.js';
|
|
10
|
+
import type { FieldExtractor } from '../field-extractor.js';
|
|
11
|
+
import type { FieldVisibility } from '../field-types.js';
|
|
12
|
+
export interface FieldExtractionConfig {
|
|
13
|
+
language: SupportedLanguages;
|
|
14
|
+
/** AST node types that are class/struct/interface declarations */
|
|
15
|
+
typeDeclarationNodes: string[];
|
|
16
|
+
/** AST node types that represent field/property declarations inside a body */
|
|
17
|
+
fieldNodeTypes: string[];
|
|
18
|
+
/** AST node type(s) for the class body container (e.g., 'class_body', 'declaration_list') */
|
|
19
|
+
bodyNodeTypes: string[];
|
|
20
|
+
/** Default visibility when no modifier is present */
|
|
21
|
+
defaultVisibility: FieldVisibility;
|
|
22
|
+
/**
|
|
23
|
+
* Extract field name from a field declaration node.
|
|
24
|
+
* Use this for nodes that declare exactly one field.
|
|
25
|
+
*/
|
|
26
|
+
extractName: (node: SyntaxNode) => string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Extract multiple field names from a single declaration node.
|
|
29
|
+
* Optional override for languages where one AST node can declare
|
|
30
|
+
* several fields (e.g. Ruby `attr_accessor :foo, :bar`).
|
|
31
|
+
* When present, the factory uses this instead of `extractName`.
|
|
32
|
+
*/
|
|
33
|
+
extractNames?: (node: SyntaxNode) => string[];
|
|
34
|
+
/** Extract type annotation from a field declaration node */
|
|
35
|
+
extractType: (node: SyntaxNode) => string | undefined;
|
|
36
|
+
/** Extract visibility from a field declaration node */
|
|
37
|
+
extractVisibility: (node: SyntaxNode) => FieldVisibility;
|
|
38
|
+
/** Check if a field is static */
|
|
39
|
+
isStatic: (node: SyntaxNode) => boolean;
|
|
40
|
+
/** Check if a field is readonly/final/const */
|
|
41
|
+
isReadonly: (node: SyntaxNode) => boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a FieldExtractor from a declarative config.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createFieldExtractor(config: FieldExtractionConfig): FieldExtractor;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractors/generic.ts
|
|
2
|
+
import { BaseFieldExtractor } from '../field-extractor.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Factory
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Create a FieldExtractor from a declarative config.
|
|
8
|
+
*/
|
|
9
|
+
export function createFieldExtractor(config) {
|
|
10
|
+
const typeDeclarationSet = new Set(config.typeDeclarationNodes);
|
|
11
|
+
const fieldNodeSet = new Set(config.fieldNodeTypes);
|
|
12
|
+
const bodyNodeSet = new Set(config.bodyNodeTypes);
|
|
13
|
+
class GenericFieldExtractor extends BaseFieldExtractor {
|
|
14
|
+
language = config.language;
|
|
15
|
+
isTypeDeclaration(node) {
|
|
16
|
+
return typeDeclarationSet.has(node.type);
|
|
17
|
+
}
|
|
18
|
+
extractVisibility(node) {
|
|
19
|
+
return config.extractVisibility(node);
|
|
20
|
+
}
|
|
21
|
+
extract(node, context) {
|
|
22
|
+
if (!this.isTypeDeclaration(node))
|
|
23
|
+
return null;
|
|
24
|
+
const nameNode = node.childForFieldName('name');
|
|
25
|
+
if (!nameNode)
|
|
26
|
+
return null;
|
|
27
|
+
const ownerFqn = nameNode.text;
|
|
28
|
+
const fields = [];
|
|
29
|
+
// Find body container(s)
|
|
30
|
+
const bodies = this.findBodies(node);
|
|
31
|
+
for (const body of bodies) {
|
|
32
|
+
this.extractFieldsFromBody(body, context, fields);
|
|
33
|
+
}
|
|
34
|
+
return { ownerFqn, fields, nestedTypes: [] };
|
|
35
|
+
}
|
|
36
|
+
// ------------------------------------------------------------------
|
|
37
|
+
// private helpers
|
|
38
|
+
// ------------------------------------------------------------------
|
|
39
|
+
findBodies(node) {
|
|
40
|
+
const result = [];
|
|
41
|
+
// Try named 'body' field first
|
|
42
|
+
const bodyField = node.childForFieldName('body');
|
|
43
|
+
if (bodyField && bodyNodeSet.has(bodyField.type)) {
|
|
44
|
+
result.push(bodyField);
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
// Walk immediate children for matching body node types
|
|
48
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
49
|
+
const child = node.namedChild(i);
|
|
50
|
+
if (child && bodyNodeSet.has(child.type)) {
|
|
51
|
+
result.push(child);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Fallback: use the body field even if its type is not in bodyNodeSet
|
|
55
|
+
if (result.length === 0 && bodyField) {
|
|
56
|
+
result.push(bodyField);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
extractFieldsFromBody(body, context, out) {
|
|
61
|
+
for (let i = 0; i < body.namedChildCount; i++) {
|
|
62
|
+
const child = body.namedChild(i);
|
|
63
|
+
if (!child)
|
|
64
|
+
continue;
|
|
65
|
+
if (fieldNodeSet.has(child.type)) {
|
|
66
|
+
if (config.extractNames) {
|
|
67
|
+
// Multi-name path: one node may declare several fields (e.g. Ruby attr_accessor)
|
|
68
|
+
const names = config.extractNames(child);
|
|
69
|
+
for (const name of names) {
|
|
70
|
+
const field = this.buildField(child, name, context);
|
|
71
|
+
if (field)
|
|
72
|
+
out.push(field);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const field = this.extractSingleField(child, context);
|
|
77
|
+
if (field)
|
|
78
|
+
out.push(field);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
extractSingleField(node, context) {
|
|
84
|
+
const name = config.extractName(node);
|
|
85
|
+
if (!name)
|
|
86
|
+
return null;
|
|
87
|
+
return this.buildField(node, name, context);
|
|
88
|
+
}
|
|
89
|
+
buildField(node, name, context) {
|
|
90
|
+
if (!name)
|
|
91
|
+
return null;
|
|
92
|
+
let type = config.extractType(node) ?? null;
|
|
93
|
+
if (type) {
|
|
94
|
+
type = this.normalizeType(type);
|
|
95
|
+
const resolved = this.resolveType(type, context);
|
|
96
|
+
if (resolved)
|
|
97
|
+
type = resolved;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
name,
|
|
101
|
+
type,
|
|
102
|
+
visibility: config.extractVisibility(node),
|
|
103
|
+
isStatic: config.isStatic(node),
|
|
104
|
+
isReadonly: config.isReadonly(node),
|
|
105
|
+
sourceFile: context.filePath,
|
|
106
|
+
line: node.startPosition.row + 1,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return new GenericFieldExtractor();
|
|
111
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
|
2
|
+
import { SupportedLanguages } from '../../../config/supported-languages.js';
|
|
3
|
+
import { BaseFieldExtractor } from '../field-extractor.js';
|
|
4
|
+
import type { FieldExtractorContext, ExtractedFields, FieldVisibility } from '../field-types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Hand-written TypeScript field extractor.
|
|
7
|
+
*
|
|
8
|
+
* This exists alongside the config-based extractor in configs/typescript-javascript.ts
|
|
9
|
+
* (used for JavaScript) because TypeScript has unique requirements:
|
|
10
|
+
* 1. type_alias_declaration with object type literals (e.g., type Config = { key: string })
|
|
11
|
+
* 2. Optional property detection appending '| undefined' to types
|
|
12
|
+
* 3. Nested type discovery within class/interface bodies
|
|
13
|
+
*
|
|
14
|
+
* The config-based extractor cannot express these TS-specific capabilities.
|
|
15
|
+
* JavaScript uses the config-based version since it lacks type syntax.
|
|
16
|
+
*/
|
|
17
|
+
export declare class TypeScriptFieldExtractor extends BaseFieldExtractor {
|
|
18
|
+
language: SupportedLanguages;
|
|
19
|
+
/**
|
|
20
|
+
* Node types that represent type declarations with fields in TypeScript
|
|
21
|
+
*/
|
|
22
|
+
private static readonly TYPE_DECLARATION_NODES;
|
|
23
|
+
/**
|
|
24
|
+
* Node types that contain field definitions within class bodies
|
|
25
|
+
*/
|
|
26
|
+
private static readonly FIELD_NODE_TYPES;
|
|
27
|
+
/**
|
|
28
|
+
* Visibility modifiers in TypeScript
|
|
29
|
+
*/
|
|
30
|
+
private static readonly VISIBILITY_MODIFIERS;
|
|
31
|
+
/**
|
|
32
|
+
* Check if this node represents a type declaration with fields
|
|
33
|
+
*/
|
|
34
|
+
isTypeDeclaration(node: SyntaxNode): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Extract visibility modifier from a field node
|
|
37
|
+
*/
|
|
38
|
+
protected extractVisibility(node: SyntaxNode): FieldVisibility;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a field has the static modifier
|
|
41
|
+
*/
|
|
42
|
+
private isStatic;
|
|
43
|
+
/**
|
|
44
|
+
* Check if a field has the readonly modifier
|
|
45
|
+
*/
|
|
46
|
+
private isReadonly;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a property is optional (has ?: syntax)
|
|
49
|
+
*/
|
|
50
|
+
private isOptional;
|
|
51
|
+
/**
|
|
52
|
+
* Extract the full type text, handling complex generic types.
|
|
53
|
+
*
|
|
54
|
+
* type_annotation nodes wrap the literal ': SomeType' — only that branch
|
|
55
|
+
* needs special handling to unwrap the inner child and skip the colon.
|
|
56
|
+
* All other node kinds are already the type text itself, so normalizeType
|
|
57
|
+
* is applied directly.
|
|
58
|
+
*/
|
|
59
|
+
private extractFullType;
|
|
60
|
+
/**
|
|
61
|
+
* Extract a single field from a field definition node
|
|
62
|
+
*/
|
|
63
|
+
private extractField;
|
|
64
|
+
/**
|
|
65
|
+
* Extract fields from a class body or interface body
|
|
66
|
+
*/
|
|
67
|
+
private extractFieldsFromBody;
|
|
68
|
+
/**
|
|
69
|
+
* Extract fields from an object type (used in type aliases)
|
|
70
|
+
*/
|
|
71
|
+
private extractFieldsFromObjectType;
|
|
72
|
+
/**
|
|
73
|
+
* Extract fields from a class or interface declaration
|
|
74
|
+
*/
|
|
75
|
+
extract(node: SyntaxNode, context: FieldExtractorContext): ExtractedFields | null;
|
|
76
|
+
}
|
|
77
|
+
export declare const typescriptFieldExtractor: TypeScriptFieldExtractor;
|