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
|
@@ -10,6 +10,23 @@
|
|
|
10
10
|
* This module is language-agnostic - language-specific patterns are defined per language.
|
|
11
11
|
*/
|
|
12
12
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
13
|
+
export declare const ENTRY_POINT_PATTERNS: {
|
|
14
|
+
javascript: RegExp[];
|
|
15
|
+
typescript: RegExp[];
|
|
16
|
+
python: RegExp[];
|
|
17
|
+
java: RegExp[];
|
|
18
|
+
kotlin: RegExp[];
|
|
19
|
+
csharp: RegExp[];
|
|
20
|
+
go: RegExp[];
|
|
21
|
+
rust: RegExp[];
|
|
22
|
+
c: RegExp[];
|
|
23
|
+
cpp: RegExp[];
|
|
24
|
+
swift: RegExp[];
|
|
25
|
+
php: RegExp[];
|
|
26
|
+
ruby: RegExp[];
|
|
27
|
+
dart: RegExp[];
|
|
28
|
+
cobol: any[];
|
|
29
|
+
};
|
|
13
30
|
export interface EntryPointScoreResult {
|
|
14
31
|
score: number;
|
|
15
32
|
reasons: string[];
|
|
@@ -36,7 +36,7 @@ const UNIVERSAL_ENTRY_POINT_PATTERNS = [
|
|
|
36
36
|
/^fire[A-Z]/, // fireEvent
|
|
37
37
|
/^emit[A-Z]/, // emitEvent
|
|
38
38
|
];
|
|
39
|
-
const ENTRY_POINT_PATTERNS = {
|
|
39
|
+
export const ENTRY_POINT_PATTERNS = {
|
|
40
40
|
// JavaScript/TypeScript
|
|
41
41
|
[SupportedLanguages.JavaScript]: [
|
|
42
42
|
/^use[A-Z]/, // React hooks (useEffect, etc.)
|
|
@@ -197,11 +197,25 @@ const ENTRY_POINT_PATTERNS = {
|
|
|
197
197
|
/^perform$/, // Background jobs (Sidekiq, ActiveJob)
|
|
198
198
|
/^execute$/, // Command pattern
|
|
199
199
|
],
|
|
200
|
+
// Dart / Flutter
|
|
201
|
+
[SupportedLanguages.Dart]: [
|
|
202
|
+
/^main$/, // App entry
|
|
203
|
+
/^build$/, // Widget.build — fundamental Flutter render entry point
|
|
204
|
+
/^createState$/, // StatefulWidget.createState
|
|
205
|
+
/^initState$/, // State lifecycle initialization
|
|
206
|
+
/^dispose$/, // State lifecycle teardown
|
|
207
|
+
/^didChangeDependencies$/, // State lifecycle — InheritedWidget changes
|
|
208
|
+
/^didUpdateWidget$/, // State lifecycle — widget rebuild with new config
|
|
209
|
+
/^runApp$/, // App entry point
|
|
210
|
+
/^onEvent$/, // BLoC event handler
|
|
211
|
+
/^mapEventToState$/, // Legacy BLoC pattern
|
|
212
|
+
],
|
|
213
|
+
[SupportedLanguages.Cobol]: [], // Standalone regex processor — no tree-sitter entry points
|
|
200
214
|
};
|
|
201
215
|
/** Pre-computed merged patterns (universal + language-specific) to avoid per-call array allocation. */
|
|
202
|
-
const MERGED_ENTRY_POINT_PATTERNS = Object.fromEntries(Object.
|
|
216
|
+
const MERGED_ENTRY_POINT_PATTERNS = Object.fromEntries(Object.values(SupportedLanguages).map(lang => [
|
|
203
217
|
lang,
|
|
204
|
-
[...UNIVERSAL_ENTRY_POINT_PATTERNS, ...ENTRY_POINT_PATTERNS[lang]],
|
|
218
|
+
[...UNIVERSAL_ENTRY_POINT_PATTERNS, ...(ENTRY_POINT_PATTERNS[lang] ?? [])],
|
|
205
219
|
]));
|
|
206
220
|
// ============================================================================
|
|
207
221
|
// UTILITY PATTERNS - Functions that should be penalized
|
|
@@ -269,7 +283,7 @@ export function calculateEntryPointScore(name, language, isExported, callerCount
|
|
|
269
283
|
else {
|
|
270
284
|
// Check positive patterns
|
|
271
285
|
const allPatterns = MERGED_ENTRY_POINT_PATTERNS[language];
|
|
272
|
-
if (allPatterns
|
|
286
|
+
if (allPatterns?.some(p => p.test(name))) {
|
|
273
287
|
nameMultiplier = 1.5; // Bonus for matching entry point pattern
|
|
274
288
|
reasons.push('entry-pattern');
|
|
275
289
|
}
|
|
@@ -6,13 +6,52 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Shared between parse-worker.ts (worker pool) and parsing-processor.ts (sequential fallback).
|
|
8
8
|
*/
|
|
9
|
-
import { SyntaxNode } from './utils.js';
|
|
10
|
-
|
|
9
|
+
import { type SyntaxNode } from './utils/ast-helpers.js';
|
|
10
|
+
/** Handler type: given a node and symbol name, return true if the symbol is exported/public. */
|
|
11
|
+
export type ExportChecker = (node: SyntaxNode, name: string) => boolean;
|
|
12
|
+
/** JS/TS: walk ancestors looking for export_statement or export_specifier. */
|
|
13
|
+
export declare const tsExportChecker: ExportChecker;
|
|
14
|
+
/** Python: public if no leading underscore (convention). */
|
|
15
|
+
export declare const pythonExportChecker: ExportChecker;
|
|
16
|
+
/** Java: check for 'public' modifier — modifiers are siblings of the name node, not parents. */
|
|
17
|
+
export declare const javaExportChecker: ExportChecker;
|
|
11
18
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* @param name - The symbol name
|
|
15
|
-
* @param language - The programming language
|
|
16
|
-
* @returns true if the symbol is exported/public
|
|
19
|
+
* C#: modifier nodes are SIBLINGS of the name node inside the declaration.
|
|
20
|
+
* Walk up to the declaration node, then scan its direct children.
|
|
17
21
|
*/
|
|
18
|
-
export declare const
|
|
22
|
+
export declare const csharpExportChecker: ExportChecker;
|
|
23
|
+
/** Go: uppercase first letter = exported. */
|
|
24
|
+
export declare const goExportChecker: ExportChecker;
|
|
25
|
+
/**
|
|
26
|
+
* Rust: visibility_modifier is a SIBLING of the name node within the declaration node
|
|
27
|
+
* (function_item, struct_item, etc.), not a parent. Walk up to the declaration node,
|
|
28
|
+
* then scan its direct children.
|
|
29
|
+
*/
|
|
30
|
+
export declare const rustExportChecker: ExportChecker;
|
|
31
|
+
/**
|
|
32
|
+
* Kotlin: default visibility is public (unlike Java).
|
|
33
|
+
* visibility_modifier is inside modifiers, a sibling of the name node within the declaration.
|
|
34
|
+
*/
|
|
35
|
+
export declare const kotlinExportChecker: ExportChecker;
|
|
36
|
+
/**
|
|
37
|
+
* C/C++: functions without 'static' storage class have external linkage by default,
|
|
38
|
+
* making them globally accessible (equivalent to exported). Only functions explicitly
|
|
39
|
+
* marked 'static' are file-scoped (not exported). C++ anonymous namespaces
|
|
40
|
+
* (namespace { ... }) also give internal linkage.
|
|
41
|
+
*/
|
|
42
|
+
export declare const cCppExportChecker: ExportChecker;
|
|
43
|
+
/** PHP: check for visibility modifier or top-level scope. */
|
|
44
|
+
export declare const phpExportChecker: ExportChecker;
|
|
45
|
+
/**
|
|
46
|
+
* Swift: treat symbols as exported unless explicitly marked private/fileprivate.
|
|
47
|
+
*
|
|
48
|
+
* Swift's default access level is `internal`, which means visible to all files
|
|
49
|
+
* in the same module/target. Since GitNexus indexes at the target level,
|
|
50
|
+
* `internal` symbols should be treated as exported (cross-file visible).
|
|
51
|
+
* Only `private` and `fileprivate` symbols are truly file-scoped.
|
|
52
|
+
*/
|
|
53
|
+
export declare const swiftExportChecker: ExportChecker;
|
|
54
|
+
/** Ruby: all top-level definitions are public (no export syntax). */
|
|
55
|
+
export declare const rubyExportChecker: ExportChecker;
|
|
56
|
+
/** Dart: public if no leading underscore (convention, same as Python). */
|
|
57
|
+
export declare const dartExportChecker: ExportChecker;
|
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Shared between parse-worker.ts (worker pool) and parsing-processor.ts (sequential fallback).
|
|
8
8
|
*/
|
|
9
|
-
import { findSiblingChild } from './utils.js';
|
|
10
|
-
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
9
|
+
import { findSiblingChild } from './utils/ast-helpers.js';
|
|
11
10
|
// ============================================================================
|
|
12
11
|
// Per-language export checkers
|
|
13
12
|
// ============================================================================
|
|
14
13
|
/** JS/TS: walk ancestors looking for export_statement or export_specifier. */
|
|
15
|
-
const tsExportChecker = (node, _name) => {
|
|
14
|
+
export const tsExportChecker = (node, _name) => {
|
|
16
15
|
let current = node;
|
|
17
16
|
while (current) {
|
|
18
17
|
const type = current.type;
|
|
@@ -30,9 +29,9 @@ const tsExportChecker = (node, _name) => {
|
|
|
30
29
|
return false;
|
|
31
30
|
};
|
|
32
31
|
/** Python: public if no leading underscore (convention). */
|
|
33
|
-
const pythonExportChecker = (_node, name) => !name.startsWith('_');
|
|
32
|
+
export const pythonExportChecker = (_node, name) => !name.startsWith('_');
|
|
34
33
|
/** Java: check for 'public' modifier — modifiers are siblings of the name node, not parents. */
|
|
35
|
-
const javaExportChecker = (node, _name) => {
|
|
34
|
+
export const javaExportChecker = (node, _name) => {
|
|
36
35
|
let current = node;
|
|
37
36
|
while (current) {
|
|
38
37
|
if (current.parent) {
|
|
@@ -66,7 +65,7 @@ const CSHARP_DECL_TYPES = new Set([
|
|
|
66
65
|
* C#: modifier nodes are SIBLINGS of the name node inside the declaration.
|
|
67
66
|
* Walk up to the declaration node, then scan its direct children.
|
|
68
67
|
*/
|
|
69
|
-
const csharpExportChecker = (node, _name) => {
|
|
68
|
+
export const csharpExportChecker = (node, _name) => {
|
|
70
69
|
let current = node;
|
|
71
70
|
while (current) {
|
|
72
71
|
if (CSHARP_DECL_TYPES.has(current.type)) {
|
|
@@ -82,7 +81,7 @@ const csharpExportChecker = (node, _name) => {
|
|
|
82
81
|
return false;
|
|
83
82
|
};
|
|
84
83
|
/** Go: uppercase first letter = exported. */
|
|
85
|
-
const goExportChecker = (_node, name) => {
|
|
84
|
+
export const goExportChecker = (_node, name) => {
|
|
86
85
|
if (name.length === 0)
|
|
87
86
|
return false;
|
|
88
87
|
const first = name[0];
|
|
@@ -99,7 +98,7 @@ const RUST_DECL_TYPES = new Set([
|
|
|
99
98
|
* (function_item, struct_item, etc.), not a parent. Walk up to the declaration node,
|
|
100
99
|
* then scan its direct children.
|
|
101
100
|
*/
|
|
102
|
-
const rustExportChecker = (node, _name) => {
|
|
101
|
+
export const rustExportChecker = (node, _name) => {
|
|
103
102
|
let current = node;
|
|
104
103
|
while (current) {
|
|
105
104
|
if (RUST_DECL_TYPES.has(current.type)) {
|
|
@@ -118,7 +117,7 @@ const rustExportChecker = (node, _name) => {
|
|
|
118
117
|
* Kotlin: default visibility is public (unlike Java).
|
|
119
118
|
* visibility_modifier is inside modifiers, a sibling of the name node within the declaration.
|
|
120
119
|
*/
|
|
121
|
-
const kotlinExportChecker = (node, _name) => {
|
|
120
|
+
export const kotlinExportChecker = (node, _name) => {
|
|
122
121
|
let current = node;
|
|
123
122
|
while (current) {
|
|
124
123
|
if (current.parent) {
|
|
@@ -142,7 +141,7 @@ const kotlinExportChecker = (node, _name) => {
|
|
|
142
141
|
* marked 'static' are file-scoped (not exported). C++ anonymous namespaces
|
|
143
142
|
* (namespace { ... }) also give internal linkage.
|
|
144
143
|
*/
|
|
145
|
-
const cCppExportChecker = (node, _name) => {
|
|
144
|
+
export const cCppExportChecker = (node, _name) => {
|
|
146
145
|
let cur = node;
|
|
147
146
|
while (cur) {
|
|
148
147
|
if (cur.type === 'function_definition' || cur.type === 'declaration') {
|
|
@@ -165,7 +164,7 @@ const cCppExportChecker = (node, _name) => {
|
|
|
165
164
|
return true; // Top-level C/C++ functions default to external linkage
|
|
166
165
|
};
|
|
167
166
|
/** PHP: check for visibility modifier or top-level scope. */
|
|
168
|
-
const phpExportChecker = (node, _name) => {
|
|
167
|
+
export const phpExportChecker = (node, _name) => {
|
|
169
168
|
let current = node;
|
|
170
169
|
while (current) {
|
|
171
170
|
if (current.type === 'class_declaration' ||
|
|
@@ -182,50 +181,30 @@ const phpExportChecker = (node, _name) => {
|
|
|
182
181
|
// Top-level functions are globally accessible
|
|
183
182
|
return true;
|
|
184
183
|
};
|
|
185
|
-
/**
|
|
186
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Swift: treat symbols as exported unless explicitly marked private/fileprivate.
|
|
186
|
+
*
|
|
187
|
+
* Swift's default access level is `internal`, which means visible to all files
|
|
188
|
+
* in the same module/target. Since GitNexus indexes at the target level,
|
|
189
|
+
* `internal` symbols should be treated as exported (cross-file visible).
|
|
190
|
+
* Only `private` and `fileprivate` symbols are truly file-scoped.
|
|
191
|
+
*/
|
|
192
|
+
export const swiftExportChecker = (node, _name) => {
|
|
187
193
|
let current = node;
|
|
188
194
|
while (current) {
|
|
189
195
|
if (current.type === 'modifiers' || current.type === 'visibility_modifier') {
|
|
190
196
|
const text = current.text || '';
|
|
191
|
-
|
|
192
|
-
|
|
197
|
+
// Exclude private(set)/fileprivate(set) — only the setter is restricted,
|
|
198
|
+
// the symbol itself is still readable cross-file.
|
|
199
|
+
if (/\b(private|fileprivate)\b(?!\s*\()/.test(text))
|
|
200
|
+
return false;
|
|
193
201
|
}
|
|
194
202
|
current = current.parent;
|
|
195
203
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// ============================================================================
|
|
199
|
-
// Exhaustive dispatch table — satisfies enforces all SupportedLanguages are covered
|
|
200
|
-
// ============================================================================
|
|
201
|
-
const exportCheckers = {
|
|
202
|
-
[SupportedLanguages.JavaScript]: tsExportChecker,
|
|
203
|
-
[SupportedLanguages.TypeScript]: tsExportChecker,
|
|
204
|
-
[SupportedLanguages.Python]: pythonExportChecker,
|
|
205
|
-
[SupportedLanguages.Java]: javaExportChecker,
|
|
206
|
-
[SupportedLanguages.CSharp]: csharpExportChecker,
|
|
207
|
-
[SupportedLanguages.Go]: goExportChecker,
|
|
208
|
-
[SupportedLanguages.Rust]: rustExportChecker,
|
|
209
|
-
[SupportedLanguages.Kotlin]: kotlinExportChecker,
|
|
210
|
-
[SupportedLanguages.C]: cCppExportChecker,
|
|
211
|
-
[SupportedLanguages.CPlusPlus]: cCppExportChecker,
|
|
212
|
-
[SupportedLanguages.PHP]: phpExportChecker,
|
|
213
|
-
[SupportedLanguages.Swift]: swiftExportChecker,
|
|
214
|
-
[SupportedLanguages.Ruby]: (_node, _name) => true,
|
|
215
|
-
};
|
|
216
|
-
// ============================================================================
|
|
217
|
-
// Public API
|
|
218
|
-
// ============================================================================
|
|
219
|
-
/**
|
|
220
|
-
* Check if a tree-sitter node is exported/public in its language.
|
|
221
|
-
* @param node - The tree-sitter AST node
|
|
222
|
-
* @param name - The symbol name
|
|
223
|
-
* @param language - The programming language
|
|
224
|
-
* @returns true if the symbol is exported/public
|
|
225
|
-
*/
|
|
226
|
-
export const isNodeExported = (node, name, language) => {
|
|
227
|
-
const checker = exportCheckers[language];
|
|
228
|
-
if (!checker)
|
|
229
|
-
return false;
|
|
230
|
-
return checker(node, name);
|
|
204
|
+
// Default (internal), public, and open are all cross-file visible
|
|
205
|
+
return true;
|
|
231
206
|
};
|
|
207
|
+
/** Ruby: all top-level definitions are public (no export syntax). */
|
|
208
|
+
export const rubyExportChecker = (_node, _name) => true;
|
|
209
|
+
/** Dart: public if no leading underscore (convention, same as Python). */
|
|
210
|
+
export const dartExportChecker = (_node, name) => !name.startsWith('_');
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SyntaxNode } from './utils/ast-helpers.js';
|
|
2
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
3
|
+
import type { FieldExtractorContext, ExtractedFields, FieldVisibility } from './field-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Language-specific field extractor
|
|
6
|
+
*/
|
|
7
|
+
export interface FieldExtractor {
|
|
8
|
+
/** Language this extractor handles */
|
|
9
|
+
language: SupportedLanguages;
|
|
10
|
+
/**
|
|
11
|
+
* Extract fields from a class/struct/interface declaration
|
|
12
|
+
*/
|
|
13
|
+
extract(node: SyntaxNode, context: FieldExtractorContext): ExtractedFields | null;
|
|
14
|
+
/**
|
|
15
|
+
* Check if this node represents a type declaration with fields
|
|
16
|
+
*/
|
|
17
|
+
isTypeDeclaration(node: SyntaxNode): boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Base class for field extractors with common utilities
|
|
21
|
+
*/
|
|
22
|
+
export declare abstract class BaseFieldExtractor implements FieldExtractor {
|
|
23
|
+
abstract language: SupportedLanguages;
|
|
24
|
+
abstract extract(node: SyntaxNode, context: FieldExtractorContext): ExtractedFields | null;
|
|
25
|
+
abstract isTypeDeclaration(node: SyntaxNode): boolean;
|
|
26
|
+
protected normalizeType(type: string | null): string | null;
|
|
27
|
+
protected resolveType(typeName: string, context: FieldExtractorContext): string | null;
|
|
28
|
+
protected abstract extractVisibility(node: SyntaxNode): FieldVisibility;
|
|
29
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractor.ts
|
|
2
|
+
/**
|
|
3
|
+
* Base class for field extractors with common utilities
|
|
4
|
+
*/
|
|
5
|
+
export class BaseFieldExtractor {
|
|
6
|
+
normalizeType(type) {
|
|
7
|
+
if (!type)
|
|
8
|
+
return null;
|
|
9
|
+
return type.trim().replace(/\s+/g, ' ');
|
|
10
|
+
}
|
|
11
|
+
resolveType(typeName, context) {
|
|
12
|
+
const { typeEnv, symbolTable, filePath } = context;
|
|
13
|
+
// Try to find in type environment (check file scope first)
|
|
14
|
+
const fileEnv = typeEnv.fileScope();
|
|
15
|
+
const local = fileEnv.get(typeName);
|
|
16
|
+
if (local)
|
|
17
|
+
return local;
|
|
18
|
+
// Try symbol table lookup in current file
|
|
19
|
+
const symbols = symbolTable.lookupExactAll(filePath, typeName);
|
|
20
|
+
if (symbols.length === 1) {
|
|
21
|
+
return symbols[0].nodeId;
|
|
22
|
+
}
|
|
23
|
+
return typeName;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractors/configs/c-cpp.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../config/supported-languages.js';
|
|
3
|
+
import { hasKeyword } from './helpers.js';
|
|
4
|
+
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* Detect C++ access specifier (public:/private:/protected:) by walking
|
|
7
|
+
* backwards from the field node through siblings.
|
|
8
|
+
*/
|
|
9
|
+
function cppAccessSpecifier(node) {
|
|
10
|
+
let sibling = node.previousNamedSibling;
|
|
11
|
+
while (sibling) {
|
|
12
|
+
if (sibling.type === 'access_specifier') {
|
|
13
|
+
const text = sibling.text.replace(':', '').trim();
|
|
14
|
+
if (text === 'public' || text === 'private' || text === 'protected')
|
|
15
|
+
return text;
|
|
16
|
+
}
|
|
17
|
+
sibling = sibling.previousNamedSibling;
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
function extractFieldName(node) {
|
|
22
|
+
// field_declaration > declarator:(field_identifier | pointer_declarator > field_identifier)
|
|
23
|
+
const declarator = node.childForFieldName('declarator');
|
|
24
|
+
if (declarator) {
|
|
25
|
+
if (declarator.type === 'field_identifier')
|
|
26
|
+
return declarator.text;
|
|
27
|
+
// pointer_declarator: *fieldName
|
|
28
|
+
for (let i = 0; i < declarator.namedChildCount; i++) {
|
|
29
|
+
const child = declarator.namedChild(i);
|
|
30
|
+
if (child?.type === 'field_identifier')
|
|
31
|
+
return child.text;
|
|
32
|
+
}
|
|
33
|
+
return declarator.text;
|
|
34
|
+
}
|
|
35
|
+
// fallback
|
|
36
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
37
|
+
const child = node.namedChild(i);
|
|
38
|
+
if (child?.type === 'field_identifier')
|
|
39
|
+
return child.text;
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
function extractFieldType(node) {
|
|
44
|
+
const typeNode = node.childForFieldName('type');
|
|
45
|
+
if (typeNode)
|
|
46
|
+
return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
|
|
47
|
+
// fallback: first child that is a type node
|
|
48
|
+
const first = node.firstNamedChild;
|
|
49
|
+
if (first && (first.type === 'type_identifier' || first.type === 'primitive_type'
|
|
50
|
+
|| first.type === 'sized_type_specifier' || first.type === 'template_type')) {
|
|
51
|
+
return extractSimpleTypeName(first) ?? first.text?.trim();
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// C++ config
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
export const cppConfig = {
|
|
59
|
+
language: SupportedLanguages.CPlusPlus,
|
|
60
|
+
typeDeclarationNodes: [
|
|
61
|
+
'struct_specifier',
|
|
62
|
+
'class_specifier',
|
|
63
|
+
'union_specifier',
|
|
64
|
+
],
|
|
65
|
+
fieldNodeTypes: ['field_declaration'],
|
|
66
|
+
bodyNodeTypes: ['field_declaration_list'],
|
|
67
|
+
defaultVisibility: 'private', // C++ class default is private
|
|
68
|
+
extractName: extractFieldName,
|
|
69
|
+
extractType: extractFieldType,
|
|
70
|
+
extractVisibility(node) {
|
|
71
|
+
const access = cppAccessSpecifier(node);
|
|
72
|
+
if (access)
|
|
73
|
+
return access;
|
|
74
|
+
// struct default = public, class default = private
|
|
75
|
+
const parent = node.parent?.parent;
|
|
76
|
+
return parent?.type === 'struct_specifier' ? 'public' : 'private';
|
|
77
|
+
},
|
|
78
|
+
isStatic(node) {
|
|
79
|
+
return hasKeyword(node, 'static');
|
|
80
|
+
},
|
|
81
|
+
isReadonly(node) {
|
|
82
|
+
return hasKeyword(node, 'const');
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// C config (subset of C++)
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
export const cConfig = {
|
|
89
|
+
language: SupportedLanguages.C,
|
|
90
|
+
typeDeclarationNodes: [
|
|
91
|
+
'struct_specifier',
|
|
92
|
+
'union_specifier',
|
|
93
|
+
],
|
|
94
|
+
fieldNodeTypes: ['field_declaration'],
|
|
95
|
+
bodyNodeTypes: ['field_declaration_list'],
|
|
96
|
+
defaultVisibility: 'public', // C structs are always public
|
|
97
|
+
extractName: extractFieldName,
|
|
98
|
+
extractType: extractFieldType,
|
|
99
|
+
extractVisibility(_node) {
|
|
100
|
+
return 'public'; // C has no access control
|
|
101
|
+
},
|
|
102
|
+
isStatic(node) {
|
|
103
|
+
return hasKeyword(node, 'static');
|
|
104
|
+
},
|
|
105
|
+
isReadonly(node) {
|
|
106
|
+
return hasKeyword(node, 'const');
|
|
107
|
+
},
|
|
108
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FieldExtractionConfig } from '../generic.js';
|
|
2
|
+
/**
|
|
3
|
+
* C# field extraction config.
|
|
4
|
+
*
|
|
5
|
+
* Handles field_declaration and property_declaration inside class/struct/interface bodies.
|
|
6
|
+
* The body node in tree-sitter-c-sharp is 'declaration_list'.
|
|
7
|
+
*/
|
|
8
|
+
export declare const csharpConfig: FieldExtractionConfig;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractors/configs/csharp.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../config/supported-languages.js';
|
|
3
|
+
import { findVisibility, hasKeyword, hasModifier } from './helpers.js';
|
|
4
|
+
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
5
|
+
const CSHARP_VIS = new Set(['public', 'private', 'protected', 'internal']);
|
|
6
|
+
/**
|
|
7
|
+
* C# field extraction config.
|
|
8
|
+
*
|
|
9
|
+
* Handles field_declaration and property_declaration inside class/struct/interface bodies.
|
|
10
|
+
* The body node in tree-sitter-c-sharp is 'declaration_list'.
|
|
11
|
+
*/
|
|
12
|
+
export const csharpConfig = {
|
|
13
|
+
language: SupportedLanguages.CSharp,
|
|
14
|
+
typeDeclarationNodes: [
|
|
15
|
+
'class_declaration',
|
|
16
|
+
'struct_declaration',
|
|
17
|
+
'interface_declaration',
|
|
18
|
+
'record_declaration',
|
|
19
|
+
],
|
|
20
|
+
fieldNodeTypes: ['field_declaration', 'property_declaration'],
|
|
21
|
+
bodyNodeTypes: ['declaration_list'],
|
|
22
|
+
defaultVisibility: 'private',
|
|
23
|
+
extractName(node) {
|
|
24
|
+
// field_declaration > variable_declaration > variable_declarator > identifier
|
|
25
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
26
|
+
const child = node.namedChild(i);
|
|
27
|
+
if (child?.type === 'variable_declaration') {
|
|
28
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
29
|
+
const declarator = child.namedChild(j);
|
|
30
|
+
if (declarator?.type === 'variable_declarator') {
|
|
31
|
+
const name = declarator.childForFieldName('name');
|
|
32
|
+
return name?.text ?? declarator.firstNamedChild?.text;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// property_declaration: name field
|
|
38
|
+
const nameNode = node.childForFieldName('name');
|
|
39
|
+
if (nameNode)
|
|
40
|
+
return nameNode.text;
|
|
41
|
+
return undefined;
|
|
42
|
+
},
|
|
43
|
+
extractType(node) {
|
|
44
|
+
// field_declaration > variable_declaration > type:(predefined_type | identifier | ...)
|
|
45
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
46
|
+
const child = node.namedChild(i);
|
|
47
|
+
if (child?.type === 'variable_declaration') {
|
|
48
|
+
const typeNode = child.childForFieldName('type');
|
|
49
|
+
if (typeNode)
|
|
50
|
+
return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
|
|
51
|
+
// fallback: first child that is a type
|
|
52
|
+
const first = child.firstNamedChild;
|
|
53
|
+
if (first && first.type !== 'variable_declarator') {
|
|
54
|
+
return extractSimpleTypeName(first) ?? first.text?.trim();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// property_declaration: type is first named child
|
|
59
|
+
const typeNode = node.childForFieldName('type');
|
|
60
|
+
if (typeNode)
|
|
61
|
+
return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
|
|
62
|
+
return undefined;
|
|
63
|
+
},
|
|
64
|
+
extractVisibility(node) {
|
|
65
|
+
return findVisibility(node, CSHARP_VIS, 'private', 'modifier');
|
|
66
|
+
},
|
|
67
|
+
isStatic(node) {
|
|
68
|
+
return hasKeyword(node, 'static') || hasModifier(node, 'modifier', 'static');
|
|
69
|
+
},
|
|
70
|
+
isReadonly(node) {
|
|
71
|
+
return hasKeyword(node, 'readonly') || hasModifier(node, 'modifier', 'readonly');
|
|
72
|
+
},
|
|
73
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FieldExtractionConfig } from '../generic.js';
|
|
2
|
+
/**
|
|
3
|
+
* Dart field extraction config.
|
|
4
|
+
*
|
|
5
|
+
* Dart class fields appear as declaration nodes inside class_body.
|
|
6
|
+
* Visibility is convention-based: underscore prefix = private.
|
|
7
|
+
*/
|
|
8
|
+
export declare const dartConfig: FieldExtractionConfig;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/field-extractors/configs/dart.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../config/supported-languages.js';
|
|
3
|
+
import { hasKeyword } from './helpers.js';
|
|
4
|
+
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* Dart field extraction config.
|
|
7
|
+
*
|
|
8
|
+
* Dart class fields appear as declaration nodes inside class_body.
|
|
9
|
+
* Visibility is convention-based: underscore prefix = private.
|
|
10
|
+
*/
|
|
11
|
+
export const dartConfig = {
|
|
12
|
+
language: SupportedLanguages.Dart,
|
|
13
|
+
typeDeclarationNodes: ['class_definition'],
|
|
14
|
+
fieldNodeTypes: ['declaration'],
|
|
15
|
+
bodyNodeTypes: ['class_body'],
|
|
16
|
+
defaultVisibility: 'public',
|
|
17
|
+
extractName(node) {
|
|
18
|
+
// declaration > initialized_identifier_list > initialized_identifier > identifier
|
|
19
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
20
|
+
const child = node.namedChild(i);
|
|
21
|
+
if (child?.type === 'initialized_identifier_list') {
|
|
22
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
23
|
+
const init = child.namedChild(j);
|
|
24
|
+
if (init?.type === 'initialized_identifier') {
|
|
25
|
+
const ident = init.firstNamedChild;
|
|
26
|
+
if (ident?.type === 'identifier')
|
|
27
|
+
return ident.text;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (child?.type === 'initialized_identifier') {
|
|
32
|
+
const ident = child.firstNamedChild;
|
|
33
|
+
if (ident?.type === 'identifier')
|
|
34
|
+
return ident.text;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// fallback: look for direct identifier
|
|
38
|
+
const name = node.childForFieldName('name');
|
|
39
|
+
return name?.text;
|
|
40
|
+
},
|
|
41
|
+
extractType(node) {
|
|
42
|
+
// declaration > type_identifier (first named child usually)
|
|
43
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
44
|
+
const child = node.namedChild(i);
|
|
45
|
+
if (child && (child.type === 'type_identifier' || child.type === 'generic_type'
|
|
46
|
+
|| child.type === 'function_type')) {
|
|
47
|
+
return extractSimpleTypeName(child) ?? child.text?.trim();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
},
|
|
52
|
+
extractVisibility(node) {
|
|
53
|
+
// Dart uses _ prefix for private
|
|
54
|
+
// Walk to find the identifier name
|
|
55
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
56
|
+
const child = node.namedChild(i);
|
|
57
|
+
if (child?.type === 'initialized_identifier_list') {
|
|
58
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
59
|
+
const init = child.namedChild(j);
|
|
60
|
+
if (init?.type === 'initialized_identifier') {
|
|
61
|
+
const ident = init.firstNamedChild;
|
|
62
|
+
if (ident?.text?.startsWith('_'))
|
|
63
|
+
return 'private';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return 'public';
|
|
69
|
+
},
|
|
70
|
+
isStatic(node) {
|
|
71
|
+
return hasKeyword(node, 'static');
|
|
72
|
+
},
|
|
73
|
+
isReadonly(node) {
|
|
74
|
+
return hasKeyword(node, 'final') || hasKeyword(node, 'const');
|
|
75
|
+
},
|
|
76
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FieldExtractionConfig } from '../generic.js';
|
|
2
|
+
/**
|
|
3
|
+
* Go field extraction config.
|
|
4
|
+
*
|
|
5
|
+
* Go struct fields live inside type_declaration > type_spec > struct_type >
|
|
6
|
+
* field_declaration_list > field_declaration.
|
|
7
|
+
*
|
|
8
|
+
* Visibility in Go is based on the first character: uppercase = exported (public),
|
|
9
|
+
* lowercase = unexported (package).
|
|
10
|
+
*/
|
|
11
|
+
export declare const goConfig: FieldExtractionConfig;
|