gitnexus 1.4.7 → 1.4.9
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 +29 -1
- package/dist/cli/ai-context.d.ts +1 -1
- package/dist/cli/ai-context.js +1 -1
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +54 -21
- package/dist/cli/index-repo.d.ts +15 -0
- package/dist/cli/index-repo.js +115 -0
- package/dist/cli/index.js +13 -3
- package/dist/cli/setup.js +90 -10
- package/dist/cli/wiki.d.ts +4 -0
- package/dist/cli/wiki.js +174 -53
- package/dist/config/supported-languages.d.ts +33 -1
- package/dist/config/supported-languages.js +32 -0
- package/dist/core/embeddings/embedder.d.ts +6 -1
- package/dist/core/embeddings/embedder.js +65 -5
- package/dist/core/embeddings/embedding-pipeline.js +11 -9
- package/dist/core/embeddings/http-client.d.ts +31 -0
- package/dist/core/embeddings/http-client.js +179 -0
- package/dist/core/embeddings/index.d.ts +1 -0
- package/dist/core/embeddings/index.js +1 -0
- package/dist/core/embeddings/types.d.ts +1 -1
- package/dist/core/graph/graph.js +9 -1
- package/dist/core/graph/types.d.ts +11 -2
- package/dist/core/ingestion/call-processor.d.ts +66 -2
- package/dist/core/ingestion/call-processor.js +650 -30
- package/dist/core/ingestion/call-routing.d.ts +9 -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 +52 -28
- 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 +97 -2
- package/dist/core/ingestion/framework-detection.js +114 -14
- package/dist/core/ingestion/heritage-processor.js +62 -66
- package/dist/core/ingestion/import-processor.d.ts +9 -10
- package/dist/core/ingestion/import-processor.js +150 -196
- 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 +10 -1
- package/dist/core/ingestion/import-resolvers/jvm.js +159 -0
- package/dist/core/ingestion/import-resolvers/php.d.ts +25 -0
- package/dist/core/ingestion/import-resolvers/php.js +80 -0
- 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 +2 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.js +7 -0
- package/dist/core/ingestion/language-config.d.ts +6 -0
- package/dist/core/ingestion/language-config.js +13 -0
- 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/markdown-processor.d.ts +17 -0
- package/dist/core/ingestion/markdown-processor.js +124 -0
- package/dist/core/ingestion/mro-processor.js +22 -18
- package/dist/core/ingestion/named-binding-processor.d.ts +18 -0
- 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 +6 -2
- package/dist/core/ingestion/parsing-processor.js +125 -85
- package/dist/core/ingestion/pipeline.d.ts +10 -0
- package/dist/core/ingestion/pipeline.js +1235 -317
- package/dist/core/ingestion/resolution-context.d.ts +5 -0
- package/dist/core/ingestion/resolution-context.js +8 -5
- 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/symbol-table.d.ts +16 -0
- package/dist/core/ingestion/symbol-table.js +20 -6
- package/dist/core/ingestion/tree-sitter-queries.d.ts +10 -9
- package/dist/core/ingestion/tree-sitter-queries.js +274 -11
- package/dist/core/ingestion/type-env.d.ts +42 -18
- package/dist/core/ingestion/type-env.js +481 -106
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +5 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +119 -0
- package/dist/core/ingestion/type-extractors/csharp.js +149 -16
- 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 +169 -66
- package/dist/core/ingestion/type-extractors/rust.js +35 -1
- package/dist/core/ingestion/type-extractors/shared.d.ts +1 -15
- package/dist/core/ingestion/type-extractors/shared.js +14 -112
- package/dist/core/ingestion/type-extractors/swift.js +338 -7
- package/dist/core/ingestion/type-extractors/types.d.ts +40 -8
- package/dist/core/ingestion/type-extractors/typescript.js +141 -9
- package/dist/core/ingestion/utils/ast-helpers.d.ts +83 -0
- package/dist/core/ingestion/utils/ast-helpers.js +817 -0
- package/dist/core/ingestion/utils/call-analysis.d.ts +73 -0
- package/dist/core/ingestion/utils/call-analysis.js +527 -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 +55 -5
- package/dist/core/ingestion/workers/parse-worker.js +415 -225
- package/dist/core/lbug/csv-generator.js +51 -1
- package/dist/core/lbug/lbug-adapter.d.ts +10 -0
- package/dist/core/lbug/lbug-adapter.js +75 -4
- package/dist/core/lbug/schema.d.ts +8 -4
- package/dist/core/lbug/schema.js +65 -4
- 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/embedder.js +11 -3
- package/dist/mcp/core/lbug-adapter.d.ts +5 -0
- package/dist/mcp/core/lbug-adapter.js +23 -2
- package/dist/mcp/local/local-backend.d.ts +38 -5
- package/dist/mcp/local/local-backend.js +804 -63
- package/dist/mcp/resources.js +2 -0
- package/dist/mcp/tools.js +73 -4
- package/dist/server/api.d.ts +19 -1
- package/dist/server/api.js +66 -6
- package/dist/storage/git.d.ts +12 -0
- package/dist/storage/git.js +21 -0
- package/dist/storage/repo-manager.d.ts +3 -0
- package/package.json +25 -16
- package/dist/core/ingestion/named-binding-extraction.d.ts +0 -61
- package/dist/core/ingestion/named-binding-extraction.js +0 -363
- package/dist/core/ingestion/resolvers/index.d.ts +0 -18
- package/dist/core/ingestion/resolvers/index.js +0 -13
- package/dist/core/ingestion/resolvers/jvm.js +0 -87
- package/dist/core/ingestion/resolvers/php.d.ts +0 -15
- package/dist/core/ingestion/resolvers/php.js +0 -35
- 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 -138
- package/dist/core/ingestion/utils.js +0 -1290
- package/scripts/patch-tree-sitter-swift.cjs +0 -74
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
import Parser from 'tree-sitter';
|
|
2
2
|
import { isLanguageAvailable, loadParser, loadLanguage } from '../tree-sitter/parser-loader.js';
|
|
3
|
-
import {
|
|
3
|
+
import { getProvider, getProviderForFile, providersWithImplicitWiring } from './languages/index.js';
|
|
4
4
|
import { generateId } from '../../lib/utils.js';
|
|
5
|
-
import { getLanguageFromFilename
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { getLanguageFromFilename } from './utils/language-detection.js';
|
|
6
|
+
import { isVerboseIngestionEnabled } from './utils/verbose.js';
|
|
7
|
+
import { yieldToEventLoop } from './utils/event-loop.js';
|
|
8
8
|
import { getTreeSitterBufferSize } from './constants.js';
|
|
9
|
-
import {
|
|
10
|
-
import { buildSuffixIndex
|
|
11
|
-
import { callRouters } from './call-routing.js';
|
|
9
|
+
import { loadImportConfigs } from './language-config.js';
|
|
10
|
+
import { buildSuffixIndex } from './import-resolvers/utils.js';
|
|
12
11
|
const isDev = process.env.NODE_ENV === 'development';
|
|
12
|
+
/** Group files by provider (only those with implicit import wiring), then call each wirer
|
|
13
|
+
* with its own language's files. O(n) over files, O(1) per provider lookup. */
|
|
14
|
+
function wireImplicitImports(files, importMap, addImportEdge, projectConfig) {
|
|
15
|
+
if (providersWithImplicitWiring.length === 0)
|
|
16
|
+
return;
|
|
17
|
+
const grouped = new Map();
|
|
18
|
+
for (const file of files) {
|
|
19
|
+
const provider = getProviderForFile(file);
|
|
20
|
+
if (!provider?.implicitImportWirer)
|
|
21
|
+
continue;
|
|
22
|
+
let list = grouped.get(provider);
|
|
23
|
+
if (!list) {
|
|
24
|
+
list = [];
|
|
25
|
+
grouped.set(provider, list);
|
|
26
|
+
}
|
|
27
|
+
list.push(file);
|
|
28
|
+
}
|
|
29
|
+
for (const [provider, langFiles] of grouped) {
|
|
30
|
+
if (langFiles.length > 1) {
|
|
31
|
+
provider.implicitImportWirer(langFiles, importMap, addImportEdge, projectConfig);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
13
35
|
/**
|
|
14
36
|
* Check if a file path is directly inside a package directory identified by its suffix.
|
|
15
37
|
* Used by the symbol resolver for Go and C# directory-level import matching.
|
|
@@ -22,125 +44,59 @@ export function isFileInPackageDir(filePath, dirSuffix) {
|
|
|
22
44
|
const afterDir = normalized.substring(normalized.indexOf(dirSuffix) + dirSuffix.length);
|
|
23
45
|
return !afterDir.includes('/');
|
|
24
46
|
}
|
|
47
|
+
// ImportResolutionContext is defined in ./import-resolvers/types.ts — re-exported here for consumers.
|
|
25
48
|
export function buildImportResolutionContext(allPaths) {
|
|
26
49
|
const allFileList = allPaths;
|
|
27
50
|
const normalizedFileList = allFileList.map(p => p.replace(/\\/g, '/'));
|
|
28
51
|
const allFilePaths = new Set(allFileList);
|
|
29
|
-
const
|
|
30
|
-
return { allFilePaths, allFileList, normalizedFileList,
|
|
52
|
+
const index = buildSuffixIndex(normalizedFileList, allFileList);
|
|
53
|
+
return { allFilePaths, allFileList, normalizedFileList, index, resolveCache: new Map() };
|
|
31
54
|
}
|
|
55
|
+
// Config loaders extracted to ./language-config.ts (Phase 2 refactor)
|
|
56
|
+
// Resolver types are in ./import-resolvers/types.ts; named binding types in ./named-bindings/types.ts
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Import path preprocessing
|
|
59
|
+
// ============================================================================
|
|
32
60
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
61
|
+
* Clean and preprocess a raw import source text into a resolved import path.
|
|
62
|
+
* Strips quotes/angle brackets (universal) and applies provider-specific
|
|
63
|
+
* transformations (currently only Kotlin wildcard import detection).
|
|
35
64
|
*/
|
|
36
|
-
function
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (language === SupportedLanguages.Java || language === SupportedLanguages.Kotlin) {
|
|
41
|
-
const exts = language === SupportedLanguages.Java ? ['.java'] : KOTLIN_EXTENSIONS;
|
|
42
|
-
if (rawImportPath.endsWith('.*')) {
|
|
43
|
-
const matchedFiles = resolveJvmWildcard(rawImportPath, normalizedFileList, allFileList, exts, index);
|
|
44
|
-
if (matchedFiles.length === 0 && language === SupportedLanguages.Kotlin) {
|
|
45
|
-
const javaMatches = resolveJvmWildcard(rawImportPath, normalizedFileList, allFileList, ['.java'], index);
|
|
46
|
-
if (javaMatches.length > 0)
|
|
47
|
-
return { kind: 'files', files: javaMatches };
|
|
48
|
-
}
|
|
49
|
-
if (matchedFiles.length > 0)
|
|
50
|
-
return { kind: 'files', files: matchedFiles };
|
|
51
|
-
// Fall through to standard resolution
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
let memberResolved = resolveJvmMemberImport(rawImportPath, normalizedFileList, allFileList, exts, index);
|
|
55
|
-
if (!memberResolved && language === SupportedLanguages.Kotlin) {
|
|
56
|
-
memberResolved = resolveJvmMemberImport(rawImportPath, normalizedFileList, allFileList, ['.java'], index);
|
|
57
|
-
}
|
|
58
|
-
if (memberResolved)
|
|
59
|
-
return { kind: 'files', files: [memberResolved] };
|
|
60
|
-
// Fall through to standard resolution
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// Go: handle package-level imports
|
|
64
|
-
if (language === SupportedLanguages.Go && goModule && rawImportPath.startsWith(goModule.modulePath)) {
|
|
65
|
-
const pkgSuffix = resolveGoPackageDir(rawImportPath, goModule);
|
|
66
|
-
if (pkgSuffix) {
|
|
67
|
-
const pkgFiles = resolveGoPackage(rawImportPath, goModule, normalizedFileList, allFileList);
|
|
68
|
-
if (pkgFiles.length > 0) {
|
|
69
|
-
return { kind: 'package', files: pkgFiles, dirSuffix: pkgSuffix };
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Fall through if no files found (package might be external)
|
|
73
|
-
}
|
|
74
|
-
// C#: handle namespace-based imports (using directives)
|
|
75
|
-
if (language === SupportedLanguages.CSharp && csharpConfigs.length > 0) {
|
|
76
|
-
const resolvedFiles = resolveCSharpImport(rawImportPath, csharpConfigs, normalizedFileList, allFileList, index);
|
|
77
|
-
if (resolvedFiles.length > 1) {
|
|
78
|
-
const dirSuffix = resolveCSharpNamespaceDir(rawImportPath, csharpConfigs);
|
|
79
|
-
if (dirSuffix) {
|
|
80
|
-
return { kind: 'package', files: resolvedFiles, dirSuffix };
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (resolvedFiles.length > 0)
|
|
84
|
-
return { kind: 'files', files: resolvedFiles };
|
|
65
|
+
export function preprocessImportPath(sourceText, importNode, provider) {
|
|
66
|
+
const cleaned = sourceText.replace(/['"<>]/g, '');
|
|
67
|
+
// Defense-in-depth: reject null bytes and control characters (matches Ruby call-routing pattern)
|
|
68
|
+
if (!cleaned || cleaned.length > 2048 || /[\x00-\x1f]/.test(cleaned))
|
|
85
69
|
return null;
|
|
70
|
+
if (provider.importPathPreprocessor) {
|
|
71
|
+
return provider.importPathPreprocessor(cleaned, importNode);
|
|
86
72
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return null; // External framework (Foundation, UIKit, etc.)
|
|
107
|
-
}
|
|
108
|
-
// Python: relative imports (PEP 328) + proximity-based bare imports
|
|
109
|
-
// Falls through to standard suffix resolution when proximity finds no match.
|
|
110
|
-
if (language === SupportedLanguages.Python) {
|
|
111
|
-
const resolved = resolvePythonImport(filePath, rawImportPath, allFilePaths);
|
|
112
|
-
if (resolved)
|
|
113
|
-
return { kind: 'files', files: [resolved] };
|
|
114
|
-
if (rawImportPath.startsWith('.'))
|
|
115
|
-
return null; // relative but unresolved — don't suffix-match
|
|
116
|
-
}
|
|
117
|
-
// Ruby: require / require_relative
|
|
118
|
-
if (language === SupportedLanguages.Ruby) {
|
|
119
|
-
const resolved = resolveRubyImport(rawImportPath, normalizedFileList, allFileList, index);
|
|
120
|
-
return resolved ? { kind: 'files', files: [resolved] } : null;
|
|
121
|
-
}
|
|
122
|
-
// Rust: expand top-level grouped imports: use {crate::a, crate::b}
|
|
123
|
-
if (language === SupportedLanguages.Rust && rawImportPath.startsWith('{') && rawImportPath.endsWith('}')) {
|
|
124
|
-
const inner = rawImportPath.slice(1, -1);
|
|
125
|
-
const parts = inner.split(',').map(p => p.trim()).filter(Boolean);
|
|
126
|
-
const resolved = [];
|
|
127
|
-
for (const part of parts) {
|
|
128
|
-
const r = resolveRustImport(filePath, part, allFilePaths);
|
|
129
|
-
if (r)
|
|
130
|
-
resolved.push(r);
|
|
131
|
-
}
|
|
132
|
-
return resolved.length > 0 ? { kind: 'files', files: resolved } : null;
|
|
133
|
-
}
|
|
134
|
-
// Standard single-file resolution
|
|
135
|
-
const resolvedPath = resolveImportPath(filePath, rawImportPath, allFilePaths, allFileList, normalizedFileList, resolveCache, language, tsconfigPaths, index);
|
|
136
|
-
return resolvedPath ? { kind: 'files', files: [resolvedPath] } : null;
|
|
73
|
+
return cleaned;
|
|
74
|
+
}
|
|
75
|
+
/** Create IMPORTS edge helpers that share a resolved-count tracker. */
|
|
76
|
+
function createImportEdgeHelpers(graph, importMap) {
|
|
77
|
+
let totalImportsResolved = 0;
|
|
78
|
+
const addImportGraphEdge = (filePath, resolvedPath) => {
|
|
79
|
+
const sourceId = generateId('File', filePath);
|
|
80
|
+
const targetId = generateId('File', resolvedPath);
|
|
81
|
+
const relId = generateId('IMPORTS', `${filePath}->${resolvedPath}`);
|
|
82
|
+
totalImportsResolved++;
|
|
83
|
+
graph.addRelationship({ id: relId, sourceId, targetId, type: 'IMPORTS', confidence: 1.0, reason: '' });
|
|
84
|
+
};
|
|
85
|
+
const addImportEdge = (filePath, resolvedPath) => {
|
|
86
|
+
addImportGraphEdge(filePath, resolvedPath);
|
|
87
|
+
if (!importMap.has(filePath))
|
|
88
|
+
importMap.set(filePath, new Set());
|
|
89
|
+
importMap.get(filePath).add(resolvedPath);
|
|
90
|
+
};
|
|
91
|
+
return { addImportEdge, addImportGraphEdge, getResolvedCount: () => totalImportsResolved };
|
|
137
92
|
}
|
|
138
93
|
/**
|
|
139
94
|
* Apply an ImportResult: emit graph edges and update ImportMap/PackageMap.
|
|
140
95
|
* If namedBindings are provided and the import resolves to a single file,
|
|
141
96
|
* also populate the NamedImportMap for precise Tier 2a resolution.
|
|
97
|
+
* Bindings tagged with `isModuleAlias` are routed to moduleAliasMap instead.
|
|
142
98
|
*/
|
|
143
|
-
function applyImportResult(result, filePath, importMap, packageMap, addImportEdge, addImportGraphEdge, namedBindings, namedImportMap) {
|
|
99
|
+
function applyImportResult(result, filePath, importMap, packageMap, addImportEdge, addImportGraphEdge, namedBindings, namedImportMap, moduleAliasMap) {
|
|
144
100
|
if (!result)
|
|
145
101
|
return;
|
|
146
102
|
if (result.kind === 'package' && packageMap) {
|
|
@@ -158,14 +114,66 @@ function applyImportResult(result, filePath, importMap, packageMap, addImportEdg
|
|
|
158
114
|
for (const resolvedFile of files) {
|
|
159
115
|
addImportEdge(filePath, resolvedFile);
|
|
160
116
|
}
|
|
161
|
-
//
|
|
162
|
-
|
|
117
|
+
// Route module aliases (import X as Y) directly to moduleAliasMap.
|
|
118
|
+
// These are module-level aliases, not symbol bindings — they don't belong in namedImportMap.
|
|
119
|
+
if (namedBindings && moduleAliasMap && files.length === 1) {
|
|
163
120
|
const resolvedFile = files[0];
|
|
121
|
+
for (const binding of namedBindings) {
|
|
122
|
+
if (!binding.isModuleAlias)
|
|
123
|
+
continue;
|
|
124
|
+
let aliasMap = moduleAliasMap.get(filePath);
|
|
125
|
+
if (!aliasMap) {
|
|
126
|
+
aliasMap = new Map();
|
|
127
|
+
moduleAliasMap.set(filePath, aliasMap);
|
|
128
|
+
}
|
|
129
|
+
aliasMap.set(binding.local, resolvedFile);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Record named bindings for precise Tier 2a resolution.
|
|
133
|
+
// If the same local name is imported from multiple files (e.g., Java static imports
|
|
134
|
+
// of overloaded methods), remove the entry so resolution falls through to Tier 2a
|
|
135
|
+
// import-scoped which sees all candidates and can apply arity narrowing.
|
|
136
|
+
if (namedBindings && namedImportMap) {
|
|
164
137
|
if (!namedImportMap.has(filePath))
|
|
165
138
|
namedImportMap.set(filePath, new Map());
|
|
166
139
|
const fileBindings = namedImportMap.get(filePath);
|
|
167
|
-
|
|
168
|
-
|
|
140
|
+
if (files.length === 1) {
|
|
141
|
+
const resolvedFile = files[0];
|
|
142
|
+
for (const binding of namedBindings) {
|
|
143
|
+
if (binding.isModuleAlias)
|
|
144
|
+
continue; // already routed to moduleAliasMap
|
|
145
|
+
const existing = fileBindings.get(binding.local);
|
|
146
|
+
if (existing && existing.sourcePath !== resolvedFile) {
|
|
147
|
+
fileBindings.delete(binding.local);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
fileBindings.set(binding.local, { sourcePath: resolvedFile, exportedName: binding.exported });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Multi-file resolution (e.g., Rust `use crate::models::{User, Repo}`).
|
|
156
|
+
// Match each binding to a resolved file by comparing the lowercase binding name
|
|
157
|
+
// to the file's basename (without extension). If no match, skip the binding.
|
|
158
|
+
for (const binding of namedBindings) {
|
|
159
|
+
if (binding.isModuleAlias)
|
|
160
|
+
continue;
|
|
161
|
+
const lowerName = binding.exported.toLowerCase();
|
|
162
|
+
const matchedFile = files.find(f => {
|
|
163
|
+
const base = f.replace(/\\/g, '/').split('/').pop() ?? '';
|
|
164
|
+
const nameWithoutExt = base.substring(0, base.lastIndexOf('.')).toLowerCase();
|
|
165
|
+
return nameWithoutExt === lowerName;
|
|
166
|
+
});
|
|
167
|
+
if (matchedFile) {
|
|
168
|
+
const existing = fileBindings.get(binding.local);
|
|
169
|
+
if (existing && existing.sourcePath !== matchedFile) {
|
|
170
|
+
fileBindings.delete(binding.local);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
fileBindings.set(binding.local, { sourcePath: matchedFile, exportedName: binding.exported });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
}
|
|
@@ -177,6 +185,7 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
|
|
|
177
185
|
const importMap = ctx.importMap;
|
|
178
186
|
const packageMap = ctx.packageMap;
|
|
179
187
|
const namedImportMap = ctx.namedImportMap;
|
|
188
|
+
const moduleAliasMap = ctx.moduleAliasMap;
|
|
180
189
|
// Use allPaths (full repo) when available for cross-chunk resolution, else fall back to chunk files
|
|
181
190
|
const allFileList = allPaths ?? files.map(f => f.path);
|
|
182
191
|
const allFilePaths = new Set(allFileList);
|
|
@@ -190,40 +199,10 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
|
|
|
190
199
|
const index = buildSuffixIndex(normalizedFileList, allFileList);
|
|
191
200
|
// Track import statistics
|
|
192
201
|
let totalImportsFound = 0;
|
|
193
|
-
let totalImportsResolved = 0;
|
|
194
202
|
// Load language-specific configs once before the file loop
|
|
195
|
-
const
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
goModule: await loadGoModulePath(effectiveRoot),
|
|
199
|
-
composerConfig: await loadComposerConfig(effectiveRoot),
|
|
200
|
-
swiftPackageConfig: await loadSwiftPackageConfig(effectiveRoot),
|
|
201
|
-
csharpConfigs: await loadCSharpProjectConfig(effectiveRoot),
|
|
202
|
-
};
|
|
203
|
-
const resolveCtx = { allFilePaths, allFileList, normalizedFileList, index, resolveCache };
|
|
204
|
-
// Helper: add an IMPORTS edge to the graph only (no ImportMap update)
|
|
205
|
-
const addImportGraphEdge = (filePath, resolvedPath) => {
|
|
206
|
-
const sourceId = generateId('File', filePath);
|
|
207
|
-
const targetId = generateId('File', resolvedPath);
|
|
208
|
-
const relId = generateId('IMPORTS', `${filePath}->${resolvedPath}`);
|
|
209
|
-
totalImportsResolved++;
|
|
210
|
-
graph.addRelationship({
|
|
211
|
-
id: relId,
|
|
212
|
-
sourceId,
|
|
213
|
-
targetId,
|
|
214
|
-
type: 'IMPORTS',
|
|
215
|
-
confidence: 1.0,
|
|
216
|
-
reason: '',
|
|
217
|
-
});
|
|
218
|
-
};
|
|
219
|
-
// Helper: add an IMPORTS edge + update import map
|
|
220
|
-
const addImportEdge = (filePath, resolvedPath) => {
|
|
221
|
-
addImportGraphEdge(filePath, resolvedPath);
|
|
222
|
-
if (!importMap.has(filePath)) {
|
|
223
|
-
importMap.set(filePath, new Set());
|
|
224
|
-
}
|
|
225
|
-
importMap.get(filePath).add(resolvedPath);
|
|
226
|
-
};
|
|
203
|
+
const configs = await loadImportConfigs(repoRoot || '');
|
|
204
|
+
const resolveCtx = { allFilePaths, allFileList, normalizedFileList, index, resolveCache, configs };
|
|
205
|
+
const { addImportEdge, addImportGraphEdge, getResolvedCount } = createImportEdgeHelpers(graph, importMap);
|
|
227
206
|
for (let i = 0; i < files.length; i++) {
|
|
228
207
|
const file = files[i];
|
|
229
208
|
onProgress?.(i + 1, files.length);
|
|
@@ -239,7 +218,8 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
|
|
|
239
218
|
}
|
|
240
219
|
continue;
|
|
241
220
|
}
|
|
242
|
-
const
|
|
221
|
+
const provider = getProvider(language);
|
|
222
|
+
const queryStr = provider.treeSitterQueries;
|
|
243
223
|
if (!queryStr)
|
|
244
224
|
continue;
|
|
245
225
|
// 2. ALWAYS load the language before querying (parser is stateful)
|
|
@@ -291,24 +271,23 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
|
|
|
291
271
|
}
|
|
292
272
|
return;
|
|
293
273
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
: sourceNode.text.replace(/['"<>]/g, '');
|
|
274
|
+
const rawImportPath = preprocessImportPath(sourceNode.text, captureMap['import'], provider);
|
|
275
|
+
if (!rawImportPath)
|
|
276
|
+
return;
|
|
298
277
|
totalImportsFound++;
|
|
299
|
-
const result =
|
|
300
|
-
const
|
|
301
|
-
|
|
278
|
+
const result = provider.importResolver(rawImportPath, file.path, resolveCtx);
|
|
279
|
+
const extractor = provider.namedBindingExtractor;
|
|
280
|
+
const bindings = namedImportMap && extractor ? extractor(captureMap['import']) : undefined;
|
|
281
|
+
applyImportResult(result, file.path, importMap, packageMap, addImportEdge, addImportGraphEdge, bindings, namedImportMap, moduleAliasMap);
|
|
302
282
|
}
|
|
303
283
|
// ---- Language-specific call-as-import routing (Ruby require, etc.) ----
|
|
304
284
|
if (captureMap['call']) {
|
|
305
285
|
const callNameNode = captureMap['call.name'];
|
|
306
286
|
if (callNameNode) {
|
|
307
|
-
const
|
|
308
|
-
const routed = callRouter(callNameNode.text, captureMap['call']);
|
|
287
|
+
const routed = provider.callRouter?.(callNameNode.text, captureMap['call']);
|
|
309
288
|
if (routed && routed.kind === 'import') {
|
|
310
289
|
totalImportsFound++;
|
|
311
|
-
const result =
|
|
290
|
+
const result = provider.importResolver(routed.importPath, file.path, resolveCtx);
|
|
312
291
|
applyImportResult(result, file.path, importMap, packageMap, addImportEdge, addImportGraphEdge);
|
|
313
292
|
}
|
|
314
293
|
}
|
|
@@ -316,13 +295,14 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
|
|
|
316
295
|
});
|
|
317
296
|
// Tree is now owned by the LRU cache — no manual delete needed
|
|
318
297
|
}
|
|
298
|
+
wireImplicitImports(allFileList, importMap, addImportEdge, configs);
|
|
319
299
|
if (skippedByLang && skippedByLang.size > 0) {
|
|
320
300
|
for (const [lang, count] of skippedByLang.entries()) {
|
|
321
301
|
console.warn(`[ingestion] Skipped ${count} ${lang} file(s) in import processing — ${lang} parser not available.`);
|
|
322
302
|
}
|
|
323
303
|
}
|
|
324
304
|
if (isDev) {
|
|
325
|
-
console.log(`📊 Import processing complete: ${
|
|
305
|
+
console.log(`📊 Import processing complete: ${getResolvedCount()}/${totalImportsFound} imports resolved to graph edges`);
|
|
326
306
|
}
|
|
327
307
|
};
|
|
328
308
|
// ============================================================================
|
|
@@ -332,41 +312,13 @@ export const processImportsFromExtracted = async (graph, files, extractedImports
|
|
|
332
312
|
const importMap = ctx.importMap;
|
|
333
313
|
const packageMap = ctx.packageMap;
|
|
334
314
|
const namedImportMap = ctx.namedImportMap;
|
|
315
|
+
const moduleAliasMap = ctx.moduleAliasMap;
|
|
335
316
|
const importCtx = prebuiltCtx ?? buildImportResolutionContext(files.map(f => f.path));
|
|
336
|
-
const { allFilePaths, allFileList, normalizedFileList,
|
|
317
|
+
const { allFilePaths, allFileList, normalizedFileList, index, resolveCache } = importCtx;
|
|
337
318
|
let totalImportsFound = 0;
|
|
338
|
-
|
|
339
|
-
const
|
|
340
|
-
const
|
|
341
|
-
tsconfigPaths: await loadTsconfigPaths(effectiveRoot),
|
|
342
|
-
goModule: await loadGoModulePath(effectiveRoot),
|
|
343
|
-
composerConfig: await loadComposerConfig(effectiveRoot),
|
|
344
|
-
swiftPackageConfig: await loadSwiftPackageConfig(effectiveRoot),
|
|
345
|
-
csharpConfigs: await loadCSharpProjectConfig(effectiveRoot),
|
|
346
|
-
};
|
|
347
|
-
const resolveCtx = { allFilePaths, allFileList, normalizedFileList, index, resolveCache };
|
|
348
|
-
// Helper: add an IMPORTS edge to the graph only (no ImportMap update)
|
|
349
|
-
const addImportGraphEdge = (filePath, resolvedPath) => {
|
|
350
|
-
const sourceId = generateId('File', filePath);
|
|
351
|
-
const targetId = generateId('File', resolvedPath);
|
|
352
|
-
const relId = generateId('IMPORTS', `${filePath}->${resolvedPath}`);
|
|
353
|
-
totalImportsResolved++;
|
|
354
|
-
graph.addRelationship({
|
|
355
|
-
id: relId,
|
|
356
|
-
sourceId,
|
|
357
|
-
targetId,
|
|
358
|
-
type: 'IMPORTS',
|
|
359
|
-
confidence: 1.0,
|
|
360
|
-
reason: '',
|
|
361
|
-
});
|
|
362
|
-
};
|
|
363
|
-
const addImportEdge = (filePath, resolvedPath) => {
|
|
364
|
-
addImportGraphEdge(filePath, resolvedPath);
|
|
365
|
-
if (!importMap.has(filePath)) {
|
|
366
|
-
importMap.set(filePath, new Set());
|
|
367
|
-
}
|
|
368
|
-
importMap.get(filePath).add(resolvedPath);
|
|
369
|
-
};
|
|
319
|
+
const configs = await loadImportConfigs(repoRoot || '');
|
|
320
|
+
const resolveCtx = { allFilePaths, allFileList, normalizedFileList, index, resolveCache, configs };
|
|
321
|
+
const { addImportEdge, addImportGraphEdge, getResolvedCount } = createImportEdgeHelpers(graph, importMap);
|
|
370
322
|
// Group by file for progress reporting (users see file count, not import count)
|
|
371
323
|
const importsByFile = new Map();
|
|
372
324
|
for (const imp of extractedImports) {
|
|
@@ -387,12 +339,14 @@ export const processImportsFromExtracted = async (graph, files, extractedImports
|
|
|
387
339
|
}
|
|
388
340
|
for (const imp of fileImports) {
|
|
389
341
|
totalImportsFound++;
|
|
390
|
-
const
|
|
391
|
-
|
|
342
|
+
const provider = getProvider(imp.language);
|
|
343
|
+
const result = provider.importResolver(imp.rawImportPath, filePath, resolveCtx);
|
|
344
|
+
applyImportResult(result, filePath, importMap, packageMap, addImportEdge, addImportGraphEdge, imp.namedBindings, namedImportMap, moduleAliasMap);
|
|
392
345
|
}
|
|
393
346
|
}
|
|
394
347
|
onProgress?.(totalFiles, totalFiles);
|
|
348
|
+
wireImplicitImports(files.map(f => f.path), importMap, addImportEdge, configs);
|
|
395
349
|
if (isDev) {
|
|
396
|
-
console.log(`📊 Import processing (fast path): ${
|
|
350
|
+
console.log(`📊 Import processing (fast path): ${getResolvedCount()}/${totalImportsFound} imports resolved to graph edges`);
|
|
397
351
|
}
|
|
398
352
|
};
|
|
@@ -3,20 +3,17 @@
|
|
|
3
3
|
* Handles using-directive resolution via .csproj root namespace stripping.
|
|
4
4
|
*/
|
|
5
5
|
import type { SuffixIndex } from './utils.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/** Root namespace from <RootNamespace> or assembly name (default: project directory name) */
|
|
9
|
-
rootNamespace: string;
|
|
10
|
-
/** Directory containing the .csproj file */
|
|
11
|
-
projectDir: string;
|
|
12
|
-
}
|
|
6
|
+
import type { ImportResult, ResolveCtx } from './types.js';
|
|
7
|
+
import type { CSharpProjectConfig } from '../language-config.js';
|
|
13
8
|
/**
|
|
14
|
-
* Resolve a C# using-directive import path to matching .cs files.
|
|
9
|
+
* Resolve a C# using-directive import path to matching .cs files (low-level helper).
|
|
15
10
|
* Tries single-file match first, then directory match for namespace imports.
|
|
16
11
|
*/
|
|
17
|
-
export declare function
|
|
12
|
+
export declare function resolveCSharpImportInternal(importPath: string, csharpConfigs: CSharpProjectConfig[], normalizedFileList: string[], allFileList: string[], index?: SuffixIndex): string[];
|
|
18
13
|
/**
|
|
19
14
|
* Compute the directory suffix for a C# namespace import (for PackageMap).
|
|
20
15
|
* Returns a suffix like "/ProjectDir/Models/" or null if no config matches.
|
|
21
16
|
*/
|
|
22
17
|
export declare function resolveCSharpNamespaceDir(importPath: string, csharpConfigs: CSharpProjectConfig[]): string | null;
|
|
18
|
+
/** C#: namespace-based resolution via .csproj configs, with suffix-match fallback. */
|
|
19
|
+
export declare function resolveCSharpImport(rawImportPath: string, filePath: string, ctx: ResolveCtx): ImportResult;
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
* Handles using-directive resolution via .csproj root namespace stripping.
|
|
4
4
|
*/
|
|
5
5
|
import { suffixResolve } from './utils.js';
|
|
6
|
+
import { SupportedLanguages } from '../../../config/supported-languages.js';
|
|
7
|
+
import { resolveStandard } from './standard.js';
|
|
6
8
|
/**
|
|
7
|
-
* Resolve a C# using-directive import path to matching .cs files.
|
|
9
|
+
* Resolve a C# using-directive import path to matching .cs files (low-level helper).
|
|
8
10
|
* Tries single-file match first, then directory match for namespace imports.
|
|
9
11
|
*/
|
|
10
|
-
export function
|
|
12
|
+
export function resolveCSharpImportInternal(importPath, csharpConfigs, normalizedFileList, allFileList, index) {
|
|
11
13
|
const namespacePath = importPath.replace(/\./g, '/');
|
|
12
14
|
const results = [];
|
|
13
15
|
for (const config of csharpConfigs) {
|
|
@@ -107,3 +109,19 @@ export function resolveCSharpNamespaceDir(importPath, csharpConfigs) {
|
|
|
107
109
|
}
|
|
108
110
|
return null;
|
|
109
111
|
}
|
|
112
|
+
/** C#: namespace-based resolution via .csproj configs, with suffix-match fallback. */
|
|
113
|
+
export function resolveCSharpImport(rawImportPath, filePath, ctx) {
|
|
114
|
+
const csharpConfigs = ctx.configs.csharpConfigs;
|
|
115
|
+
if (csharpConfigs.length > 0) {
|
|
116
|
+
const resolvedFiles = resolveCSharpImportInternal(rawImportPath, csharpConfigs, ctx.normalizedFileList, ctx.allFileList, ctx.index);
|
|
117
|
+
if (resolvedFiles.length > 1) {
|
|
118
|
+
const dirSuffix = resolveCSharpNamespaceDir(rawImportPath, csharpConfigs);
|
|
119
|
+
if (dirSuffix) {
|
|
120
|
+
return { kind: 'package', files: resolvedFiles, dirSuffix };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (resolvedFiles.length > 0)
|
|
124
|
+
return { kind: 'files', files: resolvedFiles };
|
|
125
|
+
}
|
|
126
|
+
return resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.CSharp);
|
|
127
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dart import resolution.
|
|
3
|
+
* Handles package: imports (local packages) and relative imports.
|
|
4
|
+
* SDK imports (dart:*) and external packages are skipped.
|
|
5
|
+
*/
|
|
6
|
+
import type { ImportResult, ResolveCtx } from './types.js';
|
|
7
|
+
export declare function resolveDartImport(rawImportPath: string, filePath: string, ctx: ResolveCtx): ImportResult;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dart import resolution.
|
|
3
|
+
* Handles package: imports (local packages) and relative imports.
|
|
4
|
+
* SDK imports (dart:*) and external packages are skipped.
|
|
5
|
+
*/
|
|
6
|
+
import { resolveStandard } from './standard.js';
|
|
7
|
+
import { SupportedLanguages } from '../../../config/supported-languages.js';
|
|
8
|
+
export function resolveDartImport(rawImportPath, filePath, ctx) {
|
|
9
|
+
// Strip surrounding quotes from configurable_uri capture
|
|
10
|
+
const stripped = rawImportPath.replace(/^['"]|['"]$/g, '');
|
|
11
|
+
// Skip dart: SDK imports (dart:async, dart:io, etc.)
|
|
12
|
+
if (stripped.startsWith('dart:'))
|
|
13
|
+
return null;
|
|
14
|
+
// Local package: imports → resolve to lib/<path>
|
|
15
|
+
if (stripped.startsWith('package:')) {
|
|
16
|
+
const slashIdx = stripped.indexOf('/');
|
|
17
|
+
if (slashIdx === -1)
|
|
18
|
+
return null;
|
|
19
|
+
const relPath = stripped.slice(slashIdx + 1);
|
|
20
|
+
const candidates = [`lib/${relPath}`, relPath];
|
|
21
|
+
const files = [];
|
|
22
|
+
for (const candidate of candidates) {
|
|
23
|
+
for (const fp of ctx.allFileList) {
|
|
24
|
+
if (fp.endsWith('/' + candidate) || fp === candidate) {
|
|
25
|
+
files.push(fp);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (files.length > 0)
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
if (files.length > 0)
|
|
33
|
+
return { kind: 'files', files };
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
// Relative imports — use standard resolution.
|
|
37
|
+
// Dart relative imports don't require a leading "./" (e.g. `import 'models.dart'`).
|
|
38
|
+
// The standard resolver only recognises paths starting with "." as relative, so
|
|
39
|
+
// prepend "./" when the path doesn't already start with "." to ensure correct
|
|
40
|
+
// same-directory resolution (without this, "models.dart" would be mangled by the
|
|
41
|
+
// generic dot-to-slash conversion intended for Java-style package imports).
|
|
42
|
+
const relPath = stripped.startsWith('.') ? stripped : './' + stripped;
|
|
43
|
+
return resolveStandard(relPath, filePath, ctx, SupportedLanguages.Dart);
|
|
44
|
+
}
|
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
* Go package import resolution.
|
|
3
3
|
* Handles Go module path-based package imports.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/** Module path (e.g., "github.com/user/repo") */
|
|
8
|
-
modulePath: string;
|
|
9
|
-
}
|
|
5
|
+
import type { ImportResult, ResolveCtx } from './types.js';
|
|
6
|
+
import type { GoModuleConfig } from '../language-config.js';
|
|
10
7
|
/**
|
|
11
8
|
* Extract the package directory suffix from a Go import path.
|
|
12
9
|
* Returns the suffix string (e.g., "/internal/auth/") or null if invalid.
|
|
@@ -17,3 +14,5 @@ export declare function resolveGoPackageDir(importPath: string, goModule: GoModu
|
|
|
17
14
|
* Returns an array of file paths.
|
|
18
15
|
*/
|
|
19
16
|
export declare function resolveGoPackage(importPath: string, goModule: GoModuleConfig, normalizedFileList: string[], allFileList: string[]): string[];
|
|
17
|
+
/** Go: package-level imports via go.mod module path. */
|
|
18
|
+
export declare function resolveGoImport(rawImportPath: string, filePath: string, ctx: ResolveCtx): ImportResult;
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Go package import resolution.
|
|
3
3
|
* Handles Go module path-based package imports.
|
|
4
4
|
*/
|
|
5
|
+
import { SupportedLanguages } from '../../../config/supported-languages.js';
|
|
6
|
+
import { resolveStandard } from './standard.js';
|
|
5
7
|
/**
|
|
6
8
|
* Extract the package directory suffix from a Go import path.
|
|
7
9
|
* Returns the suffix string (e.g., "/internal/auth/") or null if invalid.
|
|
@@ -40,3 +42,18 @@ export function resolveGoPackage(importPath, goModule, normalizedFileList, allFi
|
|
|
40
42
|
}
|
|
41
43
|
return matches;
|
|
42
44
|
}
|
|
45
|
+
/** Go: package-level imports via go.mod module path. */
|
|
46
|
+
export function resolveGoImport(rawImportPath, filePath, ctx) {
|
|
47
|
+
const goModule = ctx.configs.goModule;
|
|
48
|
+
if (goModule && rawImportPath.startsWith(goModule.modulePath)) {
|
|
49
|
+
const pkgSuffix = resolveGoPackageDir(rawImportPath, goModule);
|
|
50
|
+
if (pkgSuffix) {
|
|
51
|
+
const pkgFiles = resolveGoPackage(rawImportPath, goModule, ctx.normalizedFileList, ctx.allFileList);
|
|
52
|
+
if (pkgFiles.length > 0) {
|
|
53
|
+
return { kind: 'package', files: pkgFiles, dirSuffix: pkgSuffix };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Fall through if no files found (package might be external)
|
|
57
|
+
}
|
|
58
|
+
return resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.Go);
|
|
59
|
+
}
|