mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-05 02:43:32 +00:00
Some checks are pending
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Publish / Classify release event (push) Waiting to run
Publish / RC guard (marker + release-PR skip) (push) Blocked by required conditions
Publish / ci (push) Blocked by required conditions
Publish / Publish to npm (push) Blocked by required conditions
Publish / Build & Push RC Docker images (push) Blocked by required conditions
Scorecard / Scorecard analysis (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
* fix(swift): match repeated SPM target prefixes * test(swift): cover repeated SPM target prefixes * test(swift): cover valid prefix before later partial match * docs(swift): clarify target grouping parity scope * docs(swift): clarify target grouping parity scope * docs(swift): clarify target grouping parity scope * fix(swift): resolve imports from Package.swift targets, not path segments Stop fabricating IMPORTS from import Foundation onto a same-named folder. Declare modules from Package.swift when the manifest is usable; keep Sources/* for grouping and fail-open folder resolve minus SDK names. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(swift): keep empty Package.swift declarations and nested .target() deps external An inferred Sources/* folder is grouping-only. A dependency .target(name:) is not a module. Treat both as unresolved so import Foundation cannot bind to a decoy folder. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(swift): keep implicit IMPORTS intra-group and gate linear Package.swift resolve @_exported must not paint sibling files as implicit imports. A dedicated bench pins declaration-only resolve and (t_4n/t_n)/4 linearity. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3105) Honor member-only @_exported imports, skip comments while scanning Package.swift factories, fail-open mixed helper-built target lists, and block CoreData/CoreGraphics decoy folders on the inferred path. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3105) Match path: "." as the package root, skip block-commented Package.swift factories, read import kind from the clause only, and skip capture tests when the optional Swift grammar is missing. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): scan Swift import-kind without nested regex backtracking CodeQL js/redos flagged the comment-skipping IMPORT_KIND_RE; a linear walk keeps the same kind tokens. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): linear Package.swift factory scan and gate Swift context parseSwiftPackageManifest re-walked every prefix for comments (O(n²) in factory count). Resume the scan and cover nested factories in one pass. Wire Swift into the import-target context arm now that resolveImportTarget is 5-arg. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3105) Tighten Package.swift and import-text scanners: skip comments/strings, reject escapes, treat ident + [ as incomplete, and drop the unused factory-comment wrapper. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): prettier the @_exported availability fixture Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3105) Judge Package.swift completeness from Package(...)'s own targets: argument instead of raw-text regexes, nest block comments when reading an import kind, and strip leading ./ from declared target paths. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3105) Collect Package.swift factories only from Package(targets: [...]), fail-open on computed array elements, and treat // after a label colon as a comment. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3105) Ignore stray factories when Package() exists but omits targets:. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3105) Require the Package-scan seen box so the always-true undefined guard goes away. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
154 lines
4.4 KiB
TypeScript
154 lines
4.4 KiB
TypeScript
/**
|
|
* Swift import capture: import-kind, @_exported, and module path (R5, R6).
|
|
*/
|
|
import { describe, expect, it } from 'vitest';
|
|
import { SupportedLanguages } from '../../../../src/config/supported-languages.js';
|
|
import { emitSwiftScopeCaptures } from '../../../../src/core/ingestion/languages/swift/index.js';
|
|
import { interpretSwiftImport } from '../../../../src/core/ingestion/languages/swift/interpret.js';
|
|
import { isLanguageAvailable } from '../../../../src/core/tree-sitter/parser-loader.js';
|
|
|
|
function importsOf(src: string) {
|
|
return emitSwiftScopeCaptures(src, 'Probe.swift')
|
|
.map((match) => interpretSwiftImport(match))
|
|
.filter((imp): imp is NonNullable<typeof imp> => imp !== null);
|
|
}
|
|
|
|
const swiftAvailable = isLanguageAvailable(SupportedLanguages.Swift);
|
|
|
|
describe.skipIf(!swiftAvailable)('interpretSwiftImport via emitSwiftScopeCaptures', () => {
|
|
it('import Foundation is a namespace, not exported', () => {
|
|
expect(importsOf('import Foundation')).toEqual([
|
|
{
|
|
kind: 'namespace',
|
|
localName: 'Foundation',
|
|
importedName: 'Foundation',
|
|
targetRaw: 'Foundation',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('import struct Models.User is a named binding of User', () => {
|
|
expect(importsOf('import struct Models.User')).toEqual([
|
|
{
|
|
kind: 'named',
|
|
localName: 'User',
|
|
importedName: 'User',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('allows a block comment between import and its kind', () => {
|
|
expect(importsOf('import /* selected API */ struct Models.User')).toEqual([
|
|
{
|
|
kind: 'named',
|
|
localName: 'User',
|
|
importedName: 'User',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('allows a line comment between import and its kind', () => {
|
|
expect(importsOf('import // selected API\nstruct Models.User')).toEqual([
|
|
{
|
|
kind: 'named',
|
|
localName: 'User',
|
|
importedName: 'User',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('reads the kind after a long block comment that repeats star-slash-slash-star', () => {
|
|
const noise = '*//*'.repeat(80);
|
|
expect(importsOf(`import /* ${noise} */ struct Models.User`)).toEqual([
|
|
{
|
|
kind: 'named',
|
|
localName: 'User',
|
|
importedName: 'User',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('does not take import kind from an @available message string', () => {
|
|
expect(
|
|
importsOf('@available(*, deprecated, message: "import struct") import Foo.Bar'),
|
|
).toMatchObject([{ kind: 'namespace', targetRaw: 'Foo' }]);
|
|
});
|
|
|
|
it('preserves @testable as the same module', () => {
|
|
const [imp] = importsOf('@testable import App');
|
|
expect(imp).toMatchObject({
|
|
kind: 'namespace',
|
|
targetRaw: 'App',
|
|
});
|
|
});
|
|
|
|
it('@_exported import Models is a reexport of the module handle', () => {
|
|
expect(importsOf('@_exported import Models')).toEqual([
|
|
{
|
|
kind: 'reexport',
|
|
localName: 'Models',
|
|
importedName: 'Models',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('@_exported import struct Models.User is a reexport of User', () => {
|
|
expect(importsOf('@_exported import struct Models.User')).toEqual([
|
|
{
|
|
kind: 'reexport',
|
|
localName: 'User',
|
|
importedName: 'User',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('public import Models is not a reexport', () => {
|
|
expect(importsOf('public import Models')).toEqual([
|
|
{
|
|
kind: 'namespace',
|
|
localName: 'Models',
|
|
importedName: 'Models',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('does not treat _exported inside an @available message as @_exported', () => {
|
|
expect(importsOf('@available(*, deprecated, message: "_exported") import Models')).toEqual([
|
|
{
|
|
kind: 'namespace',
|
|
localName: 'Models',
|
|
importedName: 'Models',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('reads the kind after a comment that itself contains import', () => {
|
|
expect(importsOf('import /* import */ struct Models.User')).toEqual([
|
|
{
|
|
kind: 'named',
|
|
localName: 'User',
|
|
importedName: 'User',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('reads the kind after nested block comments', () => {
|
|
expect(importsOf('import /* outer /* inner */ */ struct Models.User')).toEqual([
|
|
{
|
|
kind: 'named',
|
|
localName: 'User',
|
|
importedName: 'User',
|
|
targetRaw: 'Models',
|
|
},
|
|
]);
|
|
});
|
|
});
|