mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-08 03:08:13 +00:00
refactor: consolidate strategies into configs, remove legacy resolvers
- Move all strategies from per-language files into their config files - Remove swift.ts and vue.ts (no shared helpers needed) - Remove legacy monolithic resolver functions from all per-language files - Remove unused legacy wrapper functions from standard.ts - Per-language files now only contain shared internal helpers - Fix lint warning in languages/php.ts (no-non-null-assertion) - Update test imports to reference configs/ instead of per-language files - All 3262+ tests pass, tsc --noEmit passes, zero lint errors Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/f8da6bc2-957c-4d20-87ba-402fa223c6c8 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
This commit is contained in:
parent
c0ae2f9283
commit
84a028f5f1
22 changed files with 394 additions and 534 deletions
|
|
@ -4,9 +4,35 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { createStandardStrategy } from '../standard.js';
|
||||
import { csharpNamespaceStrategy } from '../csharp.js';
|
||||
import { resolveCSharpImportInternal, resolveCSharpNamespaceDir } from '../csharp.js';
|
||||
|
||||
/** C# namespace-based resolution strategy via .csproj configs. */
|
||||
export const csharpNamespaceStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const csharpConfigs = ctx.configs.csharpConfigs;
|
||||
if (csharpConfigs.length > 0) {
|
||||
const resolvedFiles = resolveCSharpImportInternal(
|
||||
rawImportPath,
|
||||
csharpConfigs,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
ctx.index,
|
||||
);
|
||||
if (resolvedFiles.length > 1) {
|
||||
const dirSuffix = resolveCSharpNamespaceDir(rawImportPath, csharpConfigs);
|
||||
if (dirSuffix) {
|
||||
return { kind: 'package', files: resolvedFiles, dirSuffix };
|
||||
}
|
||||
}
|
||||
if (resolvedFiles.length > 0) return { kind: 'files', files: resolvedFiles };
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const csharpImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.CSharp,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,61 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import { dartPackageStrategy, dartRelativeStrategy } from '../dart.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { resolveStandard } from '../standard.js';
|
||||
|
||||
/**
|
||||
* Dart SDK and package: import strategy.
|
||||
* Absorbs dart: SDK imports and external packages (returns empty result to stop chain).
|
||||
* Returns null for relative imports to let the next strategy handle them.
|
||||
*/
|
||||
export const dartPackageStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
// Strip surrounding quotes from configurable_uri capture
|
||||
const stripped = rawImportPath.replace(/^['"]|['"]$/g, '');
|
||||
|
||||
// Skip dart: SDK imports (dart:async, dart:io, etc.)
|
||||
if (stripped.startsWith('dart:')) return { kind: 'files', files: [] };
|
||||
|
||||
// Local package: imports → resolve to lib/<path>
|
||||
if (stripped.startsWith('package:')) {
|
||||
const slashIdx = stripped.indexOf('/');
|
||||
if (slashIdx === -1) return { kind: 'files', files: [] };
|
||||
const relPath = stripped.slice(slashIdx + 1);
|
||||
const candidates = [`lib/${relPath}`, relPath];
|
||||
const files: string[] = [];
|
||||
for (const candidate of candidates) {
|
||||
for (const fp of ctx.allFileList) {
|
||||
if (fp.endsWith('/' + candidate) || fp === candidate) {
|
||||
files.push(fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (files.length > 0) break;
|
||||
}
|
||||
if (files.length > 0) return { kind: 'files', files };
|
||||
return { kind: 'files', files: [] }; // external package
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dart relative import strategy — prepends "./" for bare relative paths,
|
||||
* then delegates to standard resolution.
|
||||
*/
|
||||
export const dartRelativeStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const stripped = rawImportPath.replace(/^['"]|['"]$/g, '');
|
||||
const relPath = stripped.startsWith('.') ? stripped : './' + stripped;
|
||||
return resolveStandard(relPath, filePath, ctx, SupportedLanguages.Dart);
|
||||
};
|
||||
|
||||
export const dartImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Dart,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,34 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { createStandardStrategy } from '../standard.js';
|
||||
import { goPackageStrategy } from '../go.js';
|
||||
import { resolveGoPackageDir, resolveGoPackage } from '../go.js';
|
||||
|
||||
/** Go-specific package resolution strategy — resolves go.mod-based package imports. */
|
||||
export const goPackageStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const goModule = ctx.configs.goModule;
|
||||
if (goModule && rawImportPath.startsWith(goModule.modulePath)) {
|
||||
const pkgSuffix = resolveGoPackageDir(rawImportPath, goModule);
|
||||
if (pkgSuffix) {
|
||||
const pkgFiles = resolveGoPackage(
|
||||
rawImportPath,
|
||||
goModule,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
);
|
||||
if (pkgFiles.length > 0) {
|
||||
return { kind: 'package', files: pkgFiles, dirSuffix: pkgSuffix };
|
||||
}
|
||||
}
|
||||
// Fall through if no files found (package might be external)
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const goImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Go,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,113 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { createStandardStrategy } from '../standard.js';
|
||||
import { javaJvmStrategy, kotlinJvmStrategy } from '../jvm.js';
|
||||
import { resolveJvmWildcard, resolveJvmMemberImport, KOTLIN_EXTENSIONS } from '../jvm.js';
|
||||
|
||||
/** Java JVM resolution strategy — wildcard and member import resolution. */
|
||||
export const javaJvmStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
if (rawImportPath.endsWith('.*')) {
|
||||
const matchedFiles = resolveJvmWildcard(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
if (matchedFiles.length > 0) return { kind: 'files', files: matchedFiles };
|
||||
} else {
|
||||
const memberResolved = resolveJvmMemberImport(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
if (memberResolved) return { kind: 'files', files: [memberResolved] };
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Kotlin JVM resolution strategy — wildcard/member with Java-interop + top-level function imports.
|
||||
*/
|
||||
export const kotlinJvmStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
if (rawImportPath.endsWith('.*')) {
|
||||
const matchedFiles = resolveJvmWildcard(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
KOTLIN_EXTENSIONS,
|
||||
ctx.index,
|
||||
);
|
||||
if (matchedFiles.length === 0) {
|
||||
const javaMatches = resolveJvmWildcard(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
if (javaMatches.length > 0) return { kind: 'files', files: javaMatches };
|
||||
}
|
||||
if (matchedFiles.length > 0) return { kind: 'files', files: matchedFiles };
|
||||
} else {
|
||||
let memberResolved = resolveJvmMemberImport(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
KOTLIN_EXTENSIONS,
|
||||
ctx.index,
|
||||
);
|
||||
if (!memberResolved) {
|
||||
memberResolved = resolveJvmMemberImport(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
}
|
||||
if (memberResolved) return { kind: 'files', files: [memberResolved] };
|
||||
|
||||
// Kotlin: top-level function imports (e.g. import models.getUser) have only 2 segments,
|
||||
// which resolveJvmMemberImport skips (requires >=3). Fall back to package-directory scan
|
||||
// for lowercase last segments (function/property imports). Uppercase last segments
|
||||
// (class imports like models.User) fall through to standard suffix resolution.
|
||||
const segments = rawImportPath.split('.');
|
||||
const lastSeg = segments[segments.length - 1];
|
||||
if (segments.length >= 2 && lastSeg[0] && lastSeg[0] === lastSeg[0].toLowerCase()) {
|
||||
const pkgWildcard = segments.slice(0, -1).join('.') + '.*';
|
||||
let dirFiles = resolveJvmWildcard(
|
||||
pkgWildcard,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
KOTLIN_EXTENSIONS,
|
||||
ctx.index,
|
||||
);
|
||||
if (dirFiles.length === 0) {
|
||||
dirFiles = resolveJvmWildcard(
|
||||
pkgWildcard,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
}
|
||||
if (dirFiles.length > 0) return { kind: 'files', files: dirFiles };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const javaImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Java,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,25 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import { phpPsr4Strategy } from '../php.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { resolvePhpImportInternal } from '../php.js';
|
||||
|
||||
/** PHP PSR-4 resolution strategy via composer.json autoload mappings. */
|
||||
export const phpPsr4Strategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const resolved = resolvePhpImportInternal(
|
||||
rawImportPath,
|
||||
ctx.configs.composerConfig,
|
||||
ctx.allFilePaths,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
ctx.index,
|
||||
);
|
||||
return resolved ? { kind: 'files', files: [resolved] } : null;
|
||||
};
|
||||
|
||||
export const phpImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.PHP,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,29 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { createStandardStrategy } from '../standard.js';
|
||||
import { pythonImportStrategy } from '../python.js';
|
||||
import { resolvePythonImportInternal } from '../python.js';
|
||||
|
||||
/**
|
||||
* Python import resolution strategy — PEP 328 relative + proximity-based bare imports.
|
||||
* Returns null to continue chain for non-relative imports.
|
||||
* Absorbs unresolved relative imports (returns empty result to stop the chain).
|
||||
*/
|
||||
export const pythonImportStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const resolved = resolvePythonImportInternal(filePath, rawImportPath, ctx.allFilePaths);
|
||||
if (resolved) {
|
||||
ctx.resolveCache.set(`${filePath}::${rawImportPath}`, resolved);
|
||||
return { kind: 'files', files: [resolved] };
|
||||
}
|
||||
// PEP 328: unresolved relative imports should not fall through to suffix matching
|
||||
if (rawImportPath.startsWith('.')) return { kind: 'files', files: [] };
|
||||
return null;
|
||||
};
|
||||
|
||||
export const pythonImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Python,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,19 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import { rubyRequireStrategy } from '../ruby.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { suffixResolve } from '../utils.js';
|
||||
|
||||
/** Ruby require/require_relative resolution strategy. */
|
||||
export const rubyRequireStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const pathParts = rawImportPath.replace(/^\.\//, '').split('/').filter(Boolean);
|
||||
const resolved = suffixResolve(pathParts, ctx.normalizedFileList, ctx.allFileList, ctx.index);
|
||||
return resolved ? { kind: 'files', files: [resolved] } : null;
|
||||
};
|
||||
|
||||
export const rubyImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Ruby,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,55 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { createStandardStrategy } from '../standard.js';
|
||||
import { rustModuleStrategy } from '../rust.js';
|
||||
import { resolveRustImportInternal } from '../rust.js';
|
||||
|
||||
/** Rust module resolution strategy — handles grouped imports and crate/super/self paths. */
|
||||
export const rustModuleStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
filePath,
|
||||
ctx,
|
||||
) => {
|
||||
// Top-level grouped: use {crate::a, crate::b}
|
||||
if (rawImportPath.startsWith('{') && rawImportPath.endsWith('}')) {
|
||||
const inner = rawImportPath.slice(1, -1);
|
||||
const parts = inner
|
||||
.split(',')
|
||||
.map((p) => p.trim())
|
||||
.filter(Boolean);
|
||||
const resolved: string[] = [];
|
||||
for (const part of parts) {
|
||||
const r = resolveRustImportInternal(filePath, part, ctx.allFilePaths);
|
||||
if (r) resolved.push(r);
|
||||
}
|
||||
return resolved.length > 0 ? { kind: 'files', files: resolved } : null;
|
||||
}
|
||||
|
||||
// Scoped grouped: use crate::models::{User, Repo}
|
||||
const braceIdx = rawImportPath.indexOf('::{');
|
||||
if (braceIdx !== -1 && rawImportPath.endsWith('}')) {
|
||||
const pathPrefix = rawImportPath.substring(0, braceIdx);
|
||||
const braceContent = rawImportPath.substring(braceIdx + 3, rawImportPath.length - 1);
|
||||
const items = braceContent
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
const resolved: string[] = [];
|
||||
for (const item of items) {
|
||||
// Handle `use crate::models::{User, Repo as R}` — strip alias for resolution
|
||||
const itemName = item.includes(' as ') ? item.split(' as ')[0].trim() : item;
|
||||
const r = resolveRustImportInternal(filePath, `${pathPrefix}::${itemName}`, ctx.allFilePaths);
|
||||
if (r) resolved.push(r);
|
||||
}
|
||||
if (resolved.length > 0) return { kind: 'files', files: resolved };
|
||||
// Fallback: resolve the prefix path itself (e.g. crate::models -> models.rs)
|
||||
const prefixResult = resolveRustImportInternal(filePath, pathPrefix, ctx.allFilePaths);
|
||||
if (prefixResult) return { kind: 'files', files: [prefixResult] };
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const rustImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Rust,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,33 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig } from '../types.js';
|
||||
import { swiftPackageStrategy } from '../swift.js';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
|
||||
/** Swift Package.swift target map resolution strategy. */
|
||||
export const swiftPackageStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const swiftPackageConfig = ctx.configs.swiftPackageConfig;
|
||||
if (swiftPackageConfig) {
|
||||
const targetDir = swiftPackageConfig.targets.get(rawImportPath);
|
||||
if (targetDir) {
|
||||
const dirPrefix = targetDir + '/';
|
||||
const files: string[] = [];
|
||||
for (let i = 0; i < ctx.normalizedFileList.length; i++) {
|
||||
if (
|
||||
ctx.normalizedFileList[i].startsWith(dirPrefix) &&
|
||||
ctx.normalizedFileList[i].endsWith('.swift')
|
||||
) {
|
||||
files.push(ctx.allFileList[i]);
|
||||
}
|
||||
}
|
||||
if (files.length > 0) return { kind: 'files', files };
|
||||
}
|
||||
}
|
||||
return null; // External framework (Foundation, UIKit, etc.)
|
||||
};
|
||||
|
||||
export const swiftImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Swift,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
/**
|
||||
* C# namespace import resolution.
|
||||
* Handles using-directive resolution via .csproj root namespace stripping.
|
||||
* C# namespace import resolution — internal helpers.
|
||||
*
|
||||
* Strategy lives in configs/csharp.ts.
|
||||
* This file contains shared helpers for namespace-based resolution.
|
||||
*/
|
||||
|
||||
import type { SuffixIndex } from './utils.js';
|
||||
import { suffixResolve } from './utils.js';
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import { resolveStandard } from './standard.js';
|
||||
import type { CSharpProjectConfig } from '../language-config.js';
|
||||
|
||||
/**
|
||||
|
|
@ -126,39 +125,3 @@ export function resolveCSharpNamespaceDir(
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** C# namespace-based resolution strategy via .csproj configs. */
|
||||
export const csharpNamespaceStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const csharpConfigs = ctx.configs.csharpConfigs;
|
||||
if (csharpConfigs.length > 0) {
|
||||
const resolvedFiles = resolveCSharpImportInternal(
|
||||
rawImportPath,
|
||||
csharpConfigs,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
ctx.index,
|
||||
);
|
||||
if (resolvedFiles.length > 1) {
|
||||
const dirSuffix = resolveCSharpNamespaceDir(rawImportPath, csharpConfigs);
|
||||
if (dirSuffix) {
|
||||
return { kind: 'package', files: resolvedFiles, dirSuffix };
|
||||
}
|
||||
}
|
||||
if (resolvedFiles.length > 0) return { kind: 'files', files: resolvedFiles };
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/** C#: namespace-based resolution via .csproj configs, with suffix-match fallback. */
|
||||
export function resolveCSharpImport(
|
||||
rawImportPath: string,
|
||||
filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return csharpNamespaceStrategy(rawImportPath, filePath, ctx)
|
||||
?? resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.CSharp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,66 +1,19 @@
|
|||
/**
|
||||
* Dart import resolution.
|
||||
* Handles package: imports (local packages) and relative imports.
|
||||
* SDK imports (dart:*) and external packages are skipped.
|
||||
* Dart import resolution — internal helpers.
|
||||
*
|
||||
* Strategies live in configs/dart.ts.
|
||||
* This file is kept for backward compatibility with tests that import
|
||||
* resolveDartImport directly.
|
||||
*/
|
||||
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import type { ImportResult, ResolveCtx } from './types.js';
|
||||
import { resolveStandard } from './standard.js';
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
|
||||
/**
|
||||
* Dart SDK and package: import strategy.
|
||||
* Absorbs dart: SDK imports and external packages (returns empty result to stop chain).
|
||||
* Returns null for relative imports to let the next strategy handle them.
|
||||
* Legacy monolithic Dart import resolver — kept for backward compatibility with
|
||||
* existing tests. New code should use createImportResolver(dartImportConfig).
|
||||
*/
|
||||
export const dartPackageStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
// Strip surrounding quotes from configurable_uri capture
|
||||
const stripped = rawImportPath.replace(/^['"]|['"]$/g, '');
|
||||
|
||||
// Skip dart: SDK imports (dart:async, dart:io, etc.)
|
||||
if (stripped.startsWith('dart:')) return { kind: 'files', files: [] };
|
||||
|
||||
// Local package: imports → resolve to lib/<path>
|
||||
if (stripped.startsWith('package:')) {
|
||||
const slashIdx = stripped.indexOf('/');
|
||||
if (slashIdx === -1) return { kind: 'files', files: [] };
|
||||
const relPath = stripped.slice(slashIdx + 1);
|
||||
const candidates = [`lib/${relPath}`, relPath];
|
||||
const files: string[] = [];
|
||||
for (const candidate of candidates) {
|
||||
for (const fp of ctx.allFileList) {
|
||||
if (fp.endsWith('/' + candidate) || fp === candidate) {
|
||||
files.push(fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (files.length > 0) break;
|
||||
}
|
||||
if (files.length > 0) return { kind: 'files', files };
|
||||
return { kind: 'files', files: [] }; // external package
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dart relative import strategy — prepends "./" for bare relative paths,
|
||||
* then delegates to standard resolution.
|
||||
*/
|
||||
export const dartRelativeStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const stripped = rawImportPath.replace(/^['"]|['"]$/g, '');
|
||||
const relPath = stripped.startsWith('.') ? stripped : './' + stripped;
|
||||
return resolveStandard(relPath, filePath, ctx, SupportedLanguages.Dart);
|
||||
};
|
||||
|
||||
export function resolveDartImport(
|
||||
rawImportPath: string,
|
||||
filePath: string,
|
||||
|
|
@ -93,11 +46,6 @@ export function resolveDartImport(
|
|||
}
|
||||
|
||||
// Relative imports — use standard resolution.
|
||||
// Dart relative imports don't require a leading "./" (e.g. `import 'models.dart'`).
|
||||
// The standard resolver only recognises paths starting with "." as relative, so
|
||||
// prepend "./" when the path doesn't already start with "." to ensure correct
|
||||
// same-directory resolution (without this, "models.dart" would be mangled by the
|
||||
// generic dot-to-slash conversion intended for Java-style package imports).
|
||||
const relPath = stripped.startsWith('.') ? stripped : './' + stripped;
|
||||
return resolveStandard(relPath, filePath, ctx, SupportedLanguages.Dart);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
/**
|
||||
* Go package import resolution.
|
||||
* Handles Go module path-based package imports.
|
||||
* Go package import resolution — internal helpers.
|
||||
*
|
||||
* Strategy lives in configs/go.ts.
|
||||
* This file contains the shared helpers used by the strategy.
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import { resolveStandard } from './standard.js';
|
||||
import type { GoModuleConfig } from '../language-config.js';
|
||||
|
||||
/**
|
||||
|
|
@ -56,38 +55,3 @@ export function resolveGoPackage(
|
|||
|
||||
return matches;
|
||||
}
|
||||
|
||||
/** Go-specific package resolution strategy — resolves go.mod-based package imports. */
|
||||
export const goPackageStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const goModule = ctx.configs.goModule;
|
||||
if (goModule && rawImportPath.startsWith(goModule.modulePath)) {
|
||||
const pkgSuffix = resolveGoPackageDir(rawImportPath, goModule);
|
||||
if (pkgSuffix) {
|
||||
const pkgFiles = resolveGoPackage(
|
||||
rawImportPath,
|
||||
goModule,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
);
|
||||
if (pkgFiles.length > 0) {
|
||||
return { kind: 'package', files: pkgFiles, dirSuffix: pkgSuffix };
|
||||
}
|
||||
}
|
||||
// Fall through if no files found (package might be external)
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/** Go: package-level imports via go.mod module path. */
|
||||
export function resolveGoImport(
|
||||
rawImportPath: string,
|
||||
filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return goPackageStrategy(rawImportPath, filePath, ctx)
|
||||
?? resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.Go);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* JVM import resolution (Java + Kotlin).
|
||||
* Handles wildcard imports, member/static imports, and Kotlin-specific patterns.
|
||||
* JVM import resolution — internal helpers (Java + Kotlin).
|
||||
*
|
||||
* Strategies live in configs/jvm.ts.
|
||||
* This file contains shared helpers for wildcard/member resolution
|
||||
* and the Kotlin wildcard preprocessor.
|
||||
*/
|
||||
|
||||
import type { SuffixIndex } from './utils.js';
|
||||
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import { resolveStandard } from './standard.js';
|
||||
|
||||
/** Kotlin file extensions for JVM resolver reuse */
|
||||
export const KOTLIN_EXTENSIONS: readonly string[] = ['.kt', '.kts'];
|
||||
|
|
@ -125,130 +125,3 @@ export function resolveJvmMemberImport(
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Java JVM resolution strategy — wildcard and member import resolution. */
|
||||
export const javaJvmStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
if (rawImportPath.endsWith('.*')) {
|
||||
const matchedFiles = resolveJvmWildcard(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
if (matchedFiles.length > 0) return { kind: 'files', files: matchedFiles };
|
||||
} else {
|
||||
const memberResolved = resolveJvmMemberImport(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
if (memberResolved) return { kind: 'files', files: [memberResolved] };
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/** Java: JVM wildcard -> member import -> standard fallthrough */
|
||||
export function resolveJavaImport(
|
||||
rawImportPath: string,
|
||||
filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return javaJvmStrategy(rawImportPath, filePath, ctx)
|
||||
?? resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.Java);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin JVM resolution strategy — wildcard/member with Java-interop + top-level function imports.
|
||||
*/
|
||||
export const kotlinJvmStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
if (rawImportPath.endsWith('.*')) {
|
||||
const matchedFiles = resolveJvmWildcard(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
KOTLIN_EXTENSIONS,
|
||||
ctx.index,
|
||||
);
|
||||
if (matchedFiles.length === 0) {
|
||||
const javaMatches = resolveJvmWildcard(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
if (javaMatches.length > 0) return { kind: 'files', files: javaMatches };
|
||||
}
|
||||
if (matchedFiles.length > 0) return { kind: 'files', files: matchedFiles };
|
||||
} else {
|
||||
let memberResolved = resolveJvmMemberImport(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
KOTLIN_EXTENSIONS,
|
||||
ctx.index,
|
||||
);
|
||||
if (!memberResolved) {
|
||||
memberResolved = resolveJvmMemberImport(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
}
|
||||
if (memberResolved) return { kind: 'files', files: [memberResolved] };
|
||||
|
||||
// Kotlin: top-level function imports (e.g. import models.getUser) have only 2 segments,
|
||||
// which resolveJvmMemberImport skips (requires >=3). Fall back to package-directory scan
|
||||
// for lowercase last segments (function/property imports). Uppercase last segments
|
||||
// (class imports like models.User) fall through to standard suffix resolution.
|
||||
const segments = rawImportPath.split('.');
|
||||
const lastSeg = segments[segments.length - 1];
|
||||
if (segments.length >= 2 && lastSeg[0] && lastSeg[0] === lastSeg[0].toLowerCase()) {
|
||||
const pkgWildcard = segments.slice(0, -1).join('.') + '.*';
|
||||
let dirFiles = resolveJvmWildcard(
|
||||
pkgWildcard,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
KOTLIN_EXTENSIONS,
|
||||
ctx.index,
|
||||
);
|
||||
if (dirFiles.length === 0) {
|
||||
dirFiles = resolveJvmWildcard(
|
||||
pkgWildcard,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
['.java'],
|
||||
ctx.index,
|
||||
);
|
||||
}
|
||||
if (dirFiles.length > 0) return { kind: 'files', files: dirFiles };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Kotlin: JVM wildcard/member with Java-interop fallback -> top-level function imports -> standard.
|
||||
* Kotlin can import from .kt/.kts files OR from .java files (Java interop).
|
||||
*/
|
||||
export function resolveKotlinImport(
|
||||
rawImportPath: string,
|
||||
filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return kotlinJvmStrategy(rawImportPath, filePath, ctx)
|
||||
?? resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.Kotlin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
/**
|
||||
* PHP PSR-4 import resolution.
|
||||
* Handles use-statement resolution via composer.json autoload mappings.
|
||||
* PHP PSR-4 import resolution — internal helpers.
|
||||
*
|
||||
* Strategy lives in configs/php.ts.
|
||||
* This file contains the shared helper for PSR-4 resolution via composer.json.
|
||||
*/
|
||||
|
||||
import type { SuffixIndex } from './utils.js';
|
||||
import { suffixResolve } from './utils.js';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import type { ComposerConfig } from '../language-config.js';
|
||||
|
||||
/** Get or compute the sorted PSR-4 entries (cached after first call). */
|
||||
|
|
@ -91,29 +92,3 @@ export function resolvePhpImportInternal(
|
|||
const pathParts = normalized.split('/').filter(Boolean);
|
||||
return suffixResolve(pathParts, normalizedFileList, allFileList, index);
|
||||
}
|
||||
|
||||
/** PHP PSR-4 resolution strategy via composer.json autoload mappings. */
|
||||
export const phpPsr4Strategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const resolved = resolvePhpImportInternal(
|
||||
rawImportPath,
|
||||
ctx.configs.composerConfig,
|
||||
ctx.allFilePaths,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
ctx.index,
|
||||
);
|
||||
return resolved ? { kind: 'files', files: [resolved] } : null;
|
||||
};
|
||||
|
||||
/** PHP: namespace-based resolution via composer.json PSR-4. */
|
||||
export function resolvePhpImport(
|
||||
rawImportPath: string,
|
||||
_filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return phpPsr4Strategy(rawImportPath, _filePath, ctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/**
|
||||
* Python import resolution — PEP 328 relative imports and proximity-based bare imports.
|
||||
* Import system spec: PEP 302 (original), PEP 451 (current).
|
||||
*
|
||||
* Strategy lives in configs/python.ts.
|
||||
* This file contains the shared internal helper used by the strategy and tests.
|
||||
*/
|
||||
|
||||
import { tryResolveWithExtensions } from './utils.js';
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import { resolveStandard } from './standard.js';
|
||||
|
||||
/**
|
||||
* Resolve a Python import to a file path (low-level helper).
|
||||
|
|
@ -74,43 +74,3 @@ export function resolvePythonImportInternal(
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Python import resolution strategy — PEP 328 relative + proximity-based bare imports.
|
||||
* Returns null to continue chain for non-relative imports.
|
||||
* Absorbs unresolved relative imports (returns empty result to stop the chain).
|
||||
*/
|
||||
export const pythonImportStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const resolved = resolvePythonImportInternal(filePath, rawImportPath, ctx.allFilePaths);
|
||||
if (resolved) {
|
||||
ctx.resolveCache.set(`${filePath}::${rawImportPath}`, resolved);
|
||||
return { kind: 'files', files: [resolved] };
|
||||
}
|
||||
// PEP 328: unresolved relative imports should not fall through to suffix matching
|
||||
if (rawImportPath.startsWith('.')) return { kind: 'files', files: [] };
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Python: relative imports (PEP 328) + proximity-based bare imports.
|
||||
* Falls through to standard suffix resolution when proximity finds no match.
|
||||
*/
|
||||
export function resolvePythonImport(
|
||||
rawImportPath: string,
|
||||
filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
const resolved = resolvePythonImportInternal(filePath, rawImportPath, ctx.allFilePaths);
|
||||
if (resolved) {
|
||||
// Store in resolveCache so other files importing the same module skip the
|
||||
// ancestor walk. The cache key matches resolveStandard's convention.
|
||||
ctx.resolveCache.set(`${filePath}::${rawImportPath}`, resolved);
|
||||
return { kind: 'files', files: [resolved] };
|
||||
}
|
||||
if (rawImportPath.startsWith('.')) return null; // relative but unresolved -- don't suffix-match
|
||||
return resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.Python);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
/**
|
||||
* Ruby require/require_relative import resolution.
|
||||
* Handles path resolution for Ruby's require and require_relative calls.
|
||||
* Ruby require/require_relative import resolution — internal helpers.
|
||||
*
|
||||
* Strategy lives in configs/ruby.ts.
|
||||
* This file only contains the low-level helper used by the strategy.
|
||||
*/
|
||||
|
||||
import type { SuffixIndex } from './utils.js';
|
||||
import { suffixResolve } from './utils.js';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
|
||||
/**
|
||||
* Resolve a Ruby require/require_relative path to a matching .rb file (low-level helper).
|
||||
|
|
@ -22,27 +23,3 @@ export function resolveRubyImportInternal(
|
|||
const pathParts = importPath.replace(/^\.\//, '').split('/').filter(Boolean);
|
||||
return suffixResolve(pathParts, normalizedFileList, allFileList, index);
|
||||
}
|
||||
|
||||
/** Ruby require/require_relative resolution strategy. */
|
||||
export const rubyRequireStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const resolved = resolveRubyImportInternal(
|
||||
rawImportPath,
|
||||
ctx.normalizedFileList,
|
||||
ctx.allFileList,
|
||||
ctx.index,
|
||||
);
|
||||
return resolved ? { kind: 'files', files: [resolved] } : null;
|
||||
};
|
||||
|
||||
/** Ruby: require / require_relative. */
|
||||
export function resolveRubyImport(
|
||||
rawImportPath: string,
|
||||
_filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return rubyRequireStrategy(rawImportPath, _filePath, ctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
/**
|
||||
* Rust module import resolution.
|
||||
* Handles crate::, super::, self:: prefix paths and :: separators.
|
||||
* Rust module import resolution — internal helpers.
|
||||
*
|
||||
* Strategy lives in configs/rust.ts.
|
||||
* This file contains shared helpers used by the strategy and standard.ts.
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import { resolveStandard } from './standard.js';
|
||||
|
||||
/**
|
||||
* Resolve Rust use-path to a file (low-level helper).
|
||||
* Handles crate::, super::, self:: prefixes and :: path separators.
|
||||
|
|
@ -84,59 +82,3 @@ export function tryRustModulePath(modulePath: string, allFiles: Set<string>): st
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Rust module resolution strategy — handles grouped imports and crate/super/self paths. */
|
||||
export const rustModuleStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
filePath,
|
||||
ctx,
|
||||
) => {
|
||||
// Top-level grouped: use {crate::a, crate::b}
|
||||
if (rawImportPath.startsWith('{') && rawImportPath.endsWith('}')) {
|
||||
const inner = rawImportPath.slice(1, -1);
|
||||
const parts = inner
|
||||
.split(',')
|
||||
.map((p) => p.trim())
|
||||
.filter(Boolean);
|
||||
const resolved: string[] = [];
|
||||
for (const part of parts) {
|
||||
const r = resolveRustImportInternal(filePath, part, ctx.allFilePaths);
|
||||
if (r) resolved.push(r);
|
||||
}
|
||||
return resolved.length > 0 ? { kind: 'files', files: resolved } : null;
|
||||
}
|
||||
|
||||
// Scoped grouped: use crate::models::{User, Repo}
|
||||
const braceIdx = rawImportPath.indexOf('::{');
|
||||
if (braceIdx !== -1 && rawImportPath.endsWith('}')) {
|
||||
const pathPrefix = rawImportPath.substring(0, braceIdx);
|
||||
const braceContent = rawImportPath.substring(braceIdx + 3, rawImportPath.length - 1);
|
||||
const items = braceContent
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
const resolved: string[] = [];
|
||||
for (const item of items) {
|
||||
// Handle `use crate::models::{User, Repo as R}` — strip alias for resolution
|
||||
const itemName = item.includes(' as ') ? item.split(' as ')[0].trim() : item;
|
||||
const r = resolveRustImportInternal(filePath, `${pathPrefix}::${itemName}`, ctx.allFilePaths);
|
||||
if (r) resolved.push(r);
|
||||
}
|
||||
if (resolved.length > 0) return { kind: 'files', files: resolved };
|
||||
// Fallback: resolve the prefix path itself (e.g. crate::models -> models.rs)
|
||||
const prefixResult = resolveRustImportInternal(filePath, pathPrefix, ctx.allFilePaths);
|
||||
if (prefixResult) return { kind: 'files', files: [prefixResult] };
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/** Rust: expand grouped imports: use {crate::a, crate::b} and use crate::models::{User, Repo}. */
|
||||
export function resolveRustImport(
|
||||
rawImportPath: string,
|
||||
filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return rustModuleStrategy(rawImportPath, filePath, ctx)
|
||||
?? resolveStandard(rawImportPath, filePath, ctx, SupportedLanguages.Rust);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import type { SuffixIndex } from './utils.js';
|
|||
import { tryResolveWithExtensions, suffixResolve } from './utils.js';
|
||||
import { resolveRustImportInternal } from './rust.js';
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResult, ImportResolverFn, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
import type { TsconfigPaths } from '../language-config.js';
|
||||
|
||||
/** Max entries in the resolve cache. Beyond this, entries are evicted.
|
||||
|
|
@ -174,22 +174,6 @@ export function resolveStandard(
|
|||
return resolvedPath ? { kind: 'files', files: [resolvedPath] } : null;
|
||||
}
|
||||
|
||||
/** JavaScript: standard single-file resolution. */
|
||||
export const resolveJavascriptImport: ImportResolverFn = (raw, fp, ctx) =>
|
||||
resolveStandard(raw, fp, ctx, SupportedLanguages.JavaScript);
|
||||
|
||||
/** TypeScript: standard single-file resolution. */
|
||||
export const resolveTypescriptImport: ImportResolverFn = (raw, fp, ctx) =>
|
||||
resolveStandard(raw, fp, ctx, SupportedLanguages.TypeScript);
|
||||
|
||||
/** C: standard single-file resolution for #include directives. */
|
||||
export const resolveCImport: ImportResolverFn = (raw, fp, ctx) =>
|
||||
resolveStandard(raw, fp, ctx, SupportedLanguages.C);
|
||||
|
||||
/** C++: standard single-file resolution for #include directives. */
|
||||
export const resolveCppImport: ImportResolverFn = (raw, fp, ctx) =>
|
||||
resolveStandard(raw, fp, ctx, SupportedLanguages.CPlusPlus);
|
||||
|
||||
// ============================================================================
|
||||
// Strategy factory — composable hook for ImportResolutionConfig
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* Swift module import resolution.
|
||||
* Handles module imports via Package.swift target map.
|
||||
*/
|
||||
|
||||
import type { ImportResult, ImportResolverStrategy, ResolveCtx } from './types.js';
|
||||
|
||||
/** Swift Package.swift target map resolution strategy. */
|
||||
export const swiftPackageStrategy: ImportResolverStrategy = (
|
||||
rawImportPath,
|
||||
_filePath,
|
||||
ctx,
|
||||
) => {
|
||||
const swiftPackageConfig = ctx.configs.swiftPackageConfig;
|
||||
if (swiftPackageConfig) {
|
||||
const targetDir = swiftPackageConfig.targets.get(rawImportPath);
|
||||
if (targetDir) {
|
||||
const dirPrefix = targetDir + '/';
|
||||
const files: string[] = [];
|
||||
for (let i = 0; i < ctx.normalizedFileList.length; i++) {
|
||||
if (
|
||||
ctx.normalizedFileList[i].startsWith(dirPrefix) &&
|
||||
ctx.normalizedFileList[i].endsWith('.swift')
|
||||
) {
|
||||
files.push(ctx.allFileList[i]);
|
||||
}
|
||||
}
|
||||
if (files.length > 0) return { kind: 'files', files };
|
||||
}
|
||||
}
|
||||
return null; // External framework (Foundation, UIKit, etc.)
|
||||
};
|
||||
|
||||
/** Swift: module imports via Package.swift target map. */
|
||||
export function resolveSwiftImport(
|
||||
rawImportPath: string,
|
||||
_filePath: string,
|
||||
ctx: ResolveCtx,
|
||||
): ImportResult {
|
||||
return swiftPackageStrategy(rawImportPath, _filePath, ctx);
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
/**
|
||||
* Vue import resolver — delegates to TypeScript's standard resolver.
|
||||
*
|
||||
* Vue <script> blocks use the same import syntax as TypeScript (including
|
||||
* tsconfig path aliases like `@/`), so no custom resolution logic is needed.
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import { resolveStandard } from './standard.js';
|
||||
import type { ImportResolverFn } from './types.js';
|
||||
|
||||
export const resolveVueImport: ImportResolverFn = (raw, fp, ctx) =>
|
||||
resolveStandard(raw, fp, ctx, SupportedLanguages.TypeScript);
|
||||
|
|
@ -169,7 +169,8 @@ function extractEloquentRelationDescription(methodNode: SyntaxNode): string | nu
|
|||
function findRelationCall(root: SyntaxNode): SyntaxNode | null {
|
||||
const stack: SyntaxNode[] = [root];
|
||||
while (stack.length > 0) {
|
||||
const node = stack.pop()!;
|
||||
const node = stack.pop();
|
||||
if (!node) continue;
|
||||
if (node.type === 'member_call_expression') {
|
||||
const children = node.children ?? [];
|
||||
const objectNode = children.find(
|
||||
|
|
|
|||
|
|
@ -19,22 +19,22 @@ import type {
|
|||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import { buildSuffixIndex } from '../../src/core/ingestion/import-resolvers/utils.js';
|
||||
|
||||
// ── Per-language strategy imports ──────────────────────────────────────
|
||||
import { goPackageStrategy } from '../../src/core/ingestion/import-resolvers/go.js';
|
||||
// ── Per-language strategy imports (from config files) ──────────────────
|
||||
import { goPackageStrategy } from '../../src/core/ingestion/import-resolvers/configs/go.js';
|
||||
import {
|
||||
javaJvmStrategy,
|
||||
kotlinJvmStrategy,
|
||||
} from '../../src/core/ingestion/import-resolvers/jvm.js';
|
||||
import { rustModuleStrategy } from '../../src/core/ingestion/import-resolvers/rust.js';
|
||||
import { pythonImportStrategy } from '../../src/core/ingestion/import-resolvers/python.js';
|
||||
import { csharpNamespaceStrategy } from '../../src/core/ingestion/import-resolvers/csharp.js';
|
||||
import { phpPsr4Strategy } from '../../src/core/ingestion/import-resolvers/php.js';
|
||||
import { swiftPackageStrategy } from '../../src/core/ingestion/import-resolvers/swift.js';
|
||||
} from '../../src/core/ingestion/import-resolvers/configs/jvm.js';
|
||||
import { rustModuleStrategy } from '../../src/core/ingestion/import-resolvers/configs/rust.js';
|
||||
import { pythonImportStrategy } from '../../src/core/ingestion/import-resolvers/configs/python.js';
|
||||
import { csharpNamespaceStrategy } from '../../src/core/ingestion/import-resolvers/configs/csharp.js';
|
||||
import { phpPsr4Strategy } from '../../src/core/ingestion/import-resolvers/configs/php.js';
|
||||
import { swiftPackageStrategy } from '../../src/core/ingestion/import-resolvers/configs/swift.js';
|
||||
import {
|
||||
dartPackageStrategy,
|
||||
dartRelativeStrategy,
|
||||
} from '../../src/core/ingestion/import-resolvers/dart.js';
|
||||
import { rubyRequireStrategy } from '../../src/core/ingestion/import-resolvers/ruby.js';
|
||||
} from '../../src/core/ingestion/import-resolvers/configs/dart.js';
|
||||
import { rubyRequireStrategy } from '../../src/core/ingestion/import-resolvers/configs/ruby.js';
|
||||
|
||||
// ── Per-language config imports ────────────────────────────────────────
|
||||
import {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue