mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-08-28 05:25:25 +00:00
fix(swift): use official prebuilt parser runtime (#1130)
* fix(swift): use official prebuilt parser runtime Vendor the official tree-sitter-swift 0.7.1 runtime package so Swift parsing works without source-building, while keeping the repo on the current tree-sitter runtime until the broader upgrade is ready. Also preserves Swift resolver correctness for overloaded owned functions and extension-backed type duplicates now that Swift is available by default. Made-with: Cursor * fix(swift): move duplicate type ordering into provider Keep Swift extension candidate ordering behind the LanguageProvider contract and cover the Swift 0.7 init scanner path so parser runtime changes do not leak language-specific logic into shared resolution. Made-with: Cursor * fix(swift): address parser runtime review Add explicit Swift prebuild checks and vendor guidance so parser runtime packaging remains observable and maintainable.
This commit is contained in:
parent
86abc01445
commit
1f6df5fdbb
30 changed files with 31127 additions and 231 deletions
|
|
@ -3,7 +3,8 @@ WORKDIR /app
|
|||
RUN apt-get -o Acquire::Check-Valid-Until=false -o Acquire::Check-Date=false update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
|
||||
COPY . .
|
||||
RUN npm ci --ignore-scripts \
|
||||
&& node scripts/patch-tree-sitter-swift.cjs \
|
||||
&& npm rebuild tree-sitter-swift 2>&1 \
|
||||
&& node -e "require('tree-sitter-swift')" \
|
||||
&& (npm rebuild 2>&1 || true) \
|
||||
&& cd node_modules/tree-sitter-kotlin && npx --yes node-gyp rebuild 2>&1
|
||||
CMD ["npx", "vitest", "run", "test/integration", "--reporter=verbose"]
|
||||
|
|
|
|||
79
gitnexus/package-lock.json
generated
79
gitnexus/package-lock.json
generated
|
|
@ -68,7 +68,7 @@
|
|||
"tree-sitter-dart": "file:./vendor/tree-sitter-dart",
|
||||
"tree-sitter-kotlin": "^0.3.8",
|
||||
"tree-sitter-proto": "file:./vendor/tree-sitter-proto",
|
||||
"tree-sitter-swift": "^0.6.0"
|
||||
"tree-sitter-swift": "file:./vendor/tree-sitter-swift"
|
||||
}
|
||||
},
|
||||
"../gitnexus-shared": {
|
||||
|
|
@ -5065,20 +5065,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tree-sitter-cli": {
|
||||
"version": "0.23.2",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.23.2.tgz",
|
||||
"integrity": "sha512-kPPXprOqREX+C/FgUp2Qpt9jd0vSwn+hOgjzVv/7hapdoWpa+VeWId53rf4oNNd29ikheF12BYtGD/W90feMbA==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"tree-sitter": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tree-sitter-cpp": {
|
||||
"version": "0.23.4",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter-cpp/-/tree-sitter-cpp-0.23.4.tgz",
|
||||
|
|
@ -5268,49 +5254,8 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tree-sitter-swift": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter-swift/-/tree-sitter-swift-0.6.0.tgz",
|
||||
"integrity": "sha512-9vOJZes4/UFjBr4COHtp6ZHVuZYwfChSQbpneXQog04dAstfx5px3ybVX2cN+ylvLqsvVpmXLpidxxgF2rDQ7A==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": "^8.0.0",
|
||||
"node-gyp-build": "^4.8.0",
|
||||
"tree-sitter-cli": "^0.23",
|
||||
"which": "2.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.21.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree_sitter": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tree-sitter-swift/node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"license": "ISC",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/tree-sitter-swift/node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
"resolved": "vendor/tree-sitter-swift",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/tree-sitter-typescript": {
|
||||
"version": "0.23.2",
|
||||
|
|
@ -5765,6 +5710,24 @@
|
|||
"peerDependencies": {
|
||||
"tree-sitter": ">=0.21.0"
|
||||
}
|
||||
},
|
||||
"vendor/tree-sitter-swift": {
|
||||
"version": "0.7.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": "^8.0.0",
|
||||
"node-gyp-build": "^4.8.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.21.1 || ^0.22.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree-sitter": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
"test:integration": "vitest run test/integration",
|
||||
"test:watch": "vitest",
|
||||
"test:coverage": "vitest run --coverage",
|
||||
"postinstall": "node scripts/patch-tree-sitter-swift.cjs && node scripts/build-tree-sitter-dart.cjs && node scripts/build-tree-sitter-proto.cjs",
|
||||
"postinstall": "node scripts/build-tree-sitter-dart.cjs && node scripts/build-tree-sitter-proto.cjs",
|
||||
"prepare": "node scripts/build.js",
|
||||
"prepack": "node scripts/build.js"
|
||||
},
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
"tree-sitter-dart": "file:./vendor/tree-sitter-dart",
|
||||
"tree-sitter-kotlin": "^0.3.8",
|
||||
"tree-sitter-proto": "file:./vendor/tree-sitter-proto",
|
||||
"tree-sitter-swift": "^0.6.0"
|
||||
"tree-sitter-swift": "file:./vendor/tree-sitter-swift"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cli-progress": "^3.11.6",
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
* `node_modules/tree-sitter-proto/build/Release/tree_sitter_proto_binding.node`
|
||||
* — under npm-managed territory, safe on upgrade.
|
||||
*
|
||||
* Mirrors scripts/patch-tree-sitter-swift.cjs. Best-effort: if any
|
||||
* Mirrors the tree-sitter-dart build helper. Best-effort: if any
|
||||
* precondition fails (optional dep absent, no toolchain, --ignore-scripts),
|
||||
* warn and exit 0 so gitnexus install still succeeds.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* WORKAROUND: tree-sitter-swift@0.6.0 binding.gyp build failure
|
||||
*
|
||||
* Background:
|
||||
* tree-sitter-swift@0.6.0's binding.gyp contains an "actions" array that
|
||||
* invokes `tree-sitter generate` to regenerate parser.c from grammar.js.
|
||||
* This is intended for grammar developers, but the published npm package
|
||||
* already ships pre-generated parser files (parser.c, scanner.c), so the
|
||||
* actions are unnecessary for consumers. Since consumers don't have
|
||||
* tree-sitter-cli installed, the actions always fail during `npm install`.
|
||||
*
|
||||
* Why we can't just upgrade:
|
||||
* tree-sitter-swift@0.7.1 fixes this (removes postinstall, ships prebuilds),
|
||||
* but it requires tree-sitter@^0.22.1. The upstream project pins tree-sitter
|
||||
* to ^0.21.0 and all other grammar packages depend on that version.
|
||||
* Upgrading tree-sitter would be a separate breaking change.
|
||||
*
|
||||
* How this workaround works:
|
||||
* 1. tree-sitter-swift's own postinstall fails (npm warns but continues)
|
||||
* 2. This script runs as gitnexus's postinstall
|
||||
* 3. It removes the "actions" array from binding.gyp
|
||||
* 4. It rebuilds the native binding with the cleaned binding.gyp
|
||||
*
|
||||
* TODO: Remove this script when tree-sitter is upgraded to ^0.22.x,
|
||||
* which allows using tree-sitter-swift@0.7.1+ directly.
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
const swiftDir = path.join(__dirname, '..', 'node_modules', 'tree-sitter-swift');
|
||||
const bindingPath = path.join(swiftDir, 'binding.gyp');
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(bindingPath)) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(bindingPath, 'utf8');
|
||||
let needsRebuild = false;
|
||||
|
||||
if (content.includes('"actions"')) {
|
||||
// Strip Python-style comments (#) and trailing commas before JSON parsing
|
||||
const cleaned = content
|
||||
.replace(/#[^\n]*/g, '') // Remove # comments
|
||||
.replace(/,(\s*[\]}])/g, '$1'); // Remove trailing commas before ] or }
|
||||
const gyp = JSON.parse(cleaned);
|
||||
|
||||
if (gyp.targets && gyp.targets[0] && gyp.targets[0].actions) {
|
||||
delete gyp.targets[0].actions;
|
||||
fs.writeFileSync(bindingPath, JSON.stringify(gyp, null, 2) + '\n');
|
||||
console.log('[tree-sitter-swift] Patched binding.gyp (removed actions array)');
|
||||
needsRebuild = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if native binding exists
|
||||
const bindingNode = path.join(swiftDir, 'build', 'Release', 'tree_sitter_swift_binding.node');
|
||||
if (!fs.existsSync(bindingNode)) {
|
||||
needsRebuild = true;
|
||||
}
|
||||
|
||||
if (needsRebuild) {
|
||||
console.log('[tree-sitter-swift] Rebuilding native binding...');
|
||||
execSync('npx node-gyp rebuild', {
|
||||
cwd: swiftDir,
|
||||
stdio: 'pipe',
|
||||
timeout: 120000,
|
||||
});
|
||||
console.log('[tree-sitter-swift] Native binding built successfully');
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('[tree-sitter-swift] Could not build native binding:', err.message);
|
||||
console.warn(
|
||||
'[tree-sitter-swift] You may need to manually run: cd node_modules/tree-sitter-swift && npx node-gyp rebuild',
|
||||
);
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ type ReceiverSource = ReceiverEnriched['receiverSource'];
|
|||
* DAG stage 4 fallback: used when `selectDispatch` is absent or returns null.
|
||||
* Preserves pre-DAG dispatch semantics:
|
||||
* - 'constructor' → constructor branch
|
||||
* - 'free' → free branch (admits Swift/Kotlin class-target fast path)
|
||||
* - 'free' → free branch (admits class-target fast path)
|
||||
* - 'member' or undefined → owner-scoped branch
|
||||
*
|
||||
* `undefined` callForm MUST route through owner-scoped (not free) so bare
|
||||
|
|
@ -1595,41 +1595,30 @@ const disambiguateByOverloadOrArgTypes = (
|
|||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Collapse Swift-extension duplicate Class/Struct candidates to the primary
|
||||
* definition, preferring the shortest file path.
|
||||
*
|
||||
* Swift extensions (`extension User { ... }` in a separate file) create
|
||||
* multiple `Class` nodes sharing the same symbol name — one for the primary
|
||||
* declaration and one per extension file. When overload disambiguation and
|
||||
* receiver narrowing both fail to converge on a single candidate, this
|
||||
* heuristic picks the primary definition based on the assumption that it
|
||||
* lives at the shortest file path (e.g. `User.swift` over `UserExtensions.swift`).
|
||||
*
|
||||
* Intentionally narrower than {@link INSTANTIABLE_CLASS_TYPES}: only `Class`
|
||||
* and `Struct` are considered, not `Record`. Swift extensions only produce
|
||||
* `Class` duplicates in practice, and C#/Kotlin records do not exhibit the
|
||||
* same multi-file-definition pattern, so widening this set risks accidental
|
||||
* dedup of legitimately distinct record types.
|
||||
*
|
||||
* Returns a `ResolveResult` when the heuristic fires, `null` when the
|
||||
* candidate pool does not match the shape (mixed types, non-Class/Struct
|
||||
* kinds, or `length <= 1`). Callers should fall through to their own null
|
||||
* return when this helper returns `null`.
|
||||
*
|
||||
* Used by `resolveFreeCall`. Having a single source of truth prevents
|
||||
* duplication if the heuristic is ever tuned.
|
||||
*/
|
||||
const dedupSwiftExtensionCandidates = (
|
||||
const orderProviderSameNameTypeCandidates = (
|
||||
candidates: readonly SymbolDefinition[],
|
||||
typeName: string,
|
||||
filePath: string,
|
||||
): readonly SymbolDefinition[] | null => {
|
||||
const language = getLanguageFromFilename(filePath);
|
||||
if (language == null) return null;
|
||||
return (
|
||||
getProvider(language).orderSameNameTypeCandidates?.({
|
||||
typeName,
|
||||
callSiteFilePath: filePath,
|
||||
candidates,
|
||||
}) ?? null
|
||||
);
|
||||
};
|
||||
|
||||
const resolveProviderPrimaryTypeCandidate = (
|
||||
candidates: readonly SymbolDefinition[],
|
||||
tier: ResolutionTier,
|
||||
typeName: string,
|
||||
filePath: string,
|
||||
): ResolveResult | null => {
|
||||
if (candidates.length <= 1) return null;
|
||||
const allSameType = candidates.every((c) => c.type === candidates[0].type);
|
||||
if (!allSameType) return null;
|
||||
if (candidates[0].type !== 'Class' && candidates[0].type !== 'Struct') return null;
|
||||
const sorted = [...candidates].sort((a, b) => a.filePath.length - b.filePath.length);
|
||||
return toResolveResult(sorted[0], tier);
|
||||
const ordered = orderProviderSameNameTypeCandidates(candidates, typeName, filePath);
|
||||
return ordered && ordered.length > 0 ? toResolveResult(ordered[0], tier) : null;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2223,6 +2212,35 @@ const resolveMethodByOwner = (
|
|||
}
|
||||
}
|
||||
|
||||
if (!firstDef && !ambiguous) {
|
||||
const orderedTypeCandidates = orderProviderSameNameTypeCandidates(
|
||||
ctx.model.types.lookupClassByName(receiverTypeName),
|
||||
receiverTypeName,
|
||||
filePath,
|
||||
);
|
||||
if (orderedTypeCandidates) {
|
||||
for (const candidate of orderedTypeCandidates) {
|
||||
const def = canWalkMRO
|
||||
? lookupMethodByOwnerWithMRO(
|
||||
candidate.nodeId,
|
||||
methodName,
|
||||
heritageMap,
|
||||
ctx.model,
|
||||
mroStrategy,
|
||||
argCount,
|
||||
)
|
||||
: ctx.model.methods.lookupMethodByOwner(candidate.nodeId, methodName, argCount);
|
||||
if (!def) continue;
|
||||
if (!firstDef) {
|
||||
firstDef = def;
|
||||
} else if (def.nodeId !== firstDef.nodeId) {
|
||||
ambiguous = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!firstDef || ambiguous) return undefined;
|
||||
return { def: firstDef, tier: typeResolved.tier };
|
||||
};
|
||||
|
|
@ -2290,9 +2308,9 @@ export const resolveMemberCall = (
|
|||
* resolution via `ctx.resolve()`.
|
||||
*
|
||||
* Used for `foo()`, `doStuff()` — unqualified calls with no receiver.
|
||||
* Also handles Swift/Kotlin implicit constructors (`User()` without `new`)
|
||||
* by delegating to {@link resolveStaticCall} when the tiered pool contains
|
||||
* class-like targets.
|
||||
* Also handles implicit constructors (`User()` without `new`) by delegating
|
||||
* to {@link resolveStaticCall} when the tiered pool contains class-like
|
||||
* targets.
|
||||
*
|
||||
* {@link resolveCallTarget} delegates here for `callForm === 'free'`.
|
||||
*
|
||||
|
|
@ -2324,33 +2342,30 @@ export const resolveFreeCall = (
|
|||
|
||||
let filteredCandidates = filterCallableCandidates(tiered.candidates, argCount, 'free');
|
||||
|
||||
// Class-target fast path: Swift/Kotlin `User()` — free-form call targeting a
|
||||
// class. Delegates to resolveStaticCall for O(1) class + constructor lookup.
|
||||
// Class-target fast path: free-form call targeting a class. Delegates to
|
||||
// resolveStaticCall for O(1) class + constructor lookup.
|
||||
// The `.some()` trigger must stay aligned with `INSTANTIABLE_CLASS_TYPES` —
|
||||
// any type admitted here that is not in that set will cause resolveStaticCall
|
||||
// to return null, wasting two lookup passes per call. `Enum` is deliberately
|
||||
// excluded; `Record` is included so C# records and Kotlin data classes reach
|
||||
// the fast path.
|
||||
// excluded; `Record` is included so record-like class targets reach the fast
|
||||
// path.
|
||||
// Align with INSTANTIABLE_CLASS_TYPES by reusing the set directly rather
|
||||
// than enumerating literal strings. This converts an invariant that was
|
||||
// previously enforced by a comment ("keep this list aligned with
|
||||
// INSTANTIABLE_CLASS_TYPES") into one enforced structurally — any future
|
||||
// extension of the set (e.g. Kotlin `object`) propagates here automatically.
|
||||
// The `dedupSwiftExtensionCandidates` helper used in the tail of this
|
||||
// function deliberately uses a narrower literal `'Class' | 'Struct'` check
|
||||
// — Swift extensions only produce Class duplicates in practice, so Record
|
||||
// is excluded there by design. Do not collapse that helper into
|
||||
// INSTANTIABLE_CLASS_TYPES.
|
||||
// extension of the set propagates here automatically.
|
||||
// Language providers can still choose a primary same-name type candidate in
|
||||
// the tail of this function when their grammars index one logical type
|
||||
// multiple times.
|
||||
const hasClassTarget =
|
||||
filteredCandidates.length === 0 &&
|
||||
tiered.candidates.some((c) => INSTANTIABLE_CLASS_TYPES.has(c.type));
|
||||
if (hasClassTarget) {
|
||||
const staticResult = resolveStaticCall(calledName, filePath, ctx, argCount, tiered);
|
||||
if (staticResult) return staticResult;
|
||||
// Retry with constructor form: Swift/Kotlin constructor calls look like
|
||||
// free function calls (no `new` keyword). If resolveStaticCall didn't
|
||||
// match, re-filter with constructor form so CONSTRUCTOR_TARGET_TYPES
|
||||
// applies.
|
||||
// Retry with constructor form for languages whose constructor calls look
|
||||
// like free function calls. If resolveStaticCall didn't match, re-filter
|
||||
// with constructor form so CONSTRUCTOR_TARGET_TYPES applies.
|
||||
//
|
||||
// The retry fires for every null return from `resolveStaticCall`, which
|
||||
// can happen for three distinct reasons — all three are handled below:
|
||||
|
|
@ -2364,9 +2379,8 @@ export const resolveFreeCall = (
|
|||
// (b) Homonym ambiguity — two or more instantiable class candidates
|
||||
// share the name (e.g. `User` in two files, same tier). The
|
||||
// retry repopulates `filteredCandidates` with both Classes and
|
||||
// they flow into `dedupSwiftExtensionCandidates` below, which
|
||||
// either picks the shortest-path primary or null-routes.
|
||||
// Covered by the R7 Swift-extension dedup test.
|
||||
// they flow into the provider same-name candidate hook below, which
|
||||
// can pick a primary definition or null-route.
|
||||
//
|
||||
// (c) `resolveStaticCall` step 4 bailed because the tiered pool
|
||||
// contains ownerless `Constructor` nodes (some extractors emit
|
||||
|
|
@ -2391,10 +2405,13 @@ export const resolveFreeCall = (
|
|||
}
|
||||
|
||||
if (filteredCandidates.length !== 1) {
|
||||
// See `dedupSwiftExtensionCandidates` — shared helper, single source of
|
||||
// truth for the Swift-extension same-name collision heuristic.
|
||||
const deduped = dedupSwiftExtensionCandidates(filteredCandidates, tiered.tier);
|
||||
if (deduped) return deduped;
|
||||
const primary = resolveProviderPrimaryTypeCandidate(
|
||||
filteredCandidates,
|
||||
tiered.tier,
|
||||
calledName,
|
||||
filePath,
|
||||
);
|
||||
if (primary) return primary;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -2559,9 +2576,16 @@ export const resolveStaticCall = (
|
|||
// Interface / Trait / Impl). Null-route via the fall-through `return
|
||||
// null` — this is the dominant Codex-fix case.
|
||||
// length === 1 → a single instantiable candidate remains, return it.
|
||||
// length > 1 → two or more instantiable classes share the name (e.g.
|
||||
// homonym classes across files with no import narrowing). Fall through
|
||||
// to `return null` so the caller null-routes rather than guess.
|
||||
// length > 1 → let the call-site provider choose a primary when it can
|
||||
// prove the candidates are one logical type; otherwise null-route.
|
||||
const primary = resolveProviderPrimaryTypeCandidate(
|
||||
instantiableCandidates,
|
||||
typeResolved.tier,
|
||||
className,
|
||||
currentFile,
|
||||
);
|
||||
if (primary) return primary;
|
||||
|
||||
if (instantiableCandidates.length === 1) {
|
||||
return toResolveResult(instantiableCandidates[0], typeResolved.tier);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -498,6 +498,15 @@ interface LanguageProviderConfig {
|
|||
|
||||
// ── Resolution phase (RFC §4v2) ────────────────────────────────────
|
||||
|
||||
/** Order same-name type candidates when a language can index multiple
|
||||
* definitions for one logical type. Return null to keep shared ambiguity
|
||||
* handling. */
|
||||
readonly orderSameNameTypeCandidates?: (params: {
|
||||
readonly typeName: string;
|
||||
readonly callSiteFilePath: string;
|
||||
readonly candidates: readonly SymbolDefinition[];
|
||||
}) => readonly SymbolDefinition[] | null;
|
||||
|
||||
/**
|
||||
* Is this callable definition compatible with the given call-site arity?
|
||||
* Language-specific rules: Python `*args`/`**kwargs`/defaults, JS default
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { NodeLabel } from 'gitnexus-shared';
|
||||
import type { NodeLabel, SymbolDefinition } from 'gitnexus-shared';
|
||||
import { createClassExtractor } from '../class-extractors/generic.js';
|
||||
import { swiftClassConfig } from '../class-extractors/configs/swift.js';
|
||||
import { defineLanguage } from '../language-provider.js';
|
||||
|
|
@ -128,6 +128,24 @@ const swiftExtractFunctionName = (
|
|||
return null; // fall through to generic
|
||||
};
|
||||
|
||||
const orderSwiftSameNameTypeCandidates = ({
|
||||
callSiteFilePath,
|
||||
candidates,
|
||||
}: {
|
||||
readonly typeName: string;
|
||||
readonly callSiteFilePath: string;
|
||||
readonly candidates: readonly SymbolDefinition[];
|
||||
}): readonly SymbolDefinition[] | null => {
|
||||
if (!callSiteFilePath.endsWith('.swift')) return null;
|
||||
if (candidates.length <= 1) return null;
|
||||
if (!candidates.every((c) => c.type === candidates[0].type)) return null;
|
||||
if (candidates[0].type !== 'Class' && candidates[0].type !== 'Struct') return null;
|
||||
if (!candidates.every((c) => c.filePath.endsWith('.swift'))) return null;
|
||||
return [...candidates].sort(
|
||||
(a, b) => a.filePath.length - b.filePath.length || a.filePath.localeCompare(b.filePath),
|
||||
);
|
||||
};
|
||||
|
||||
const BUILT_INS: ReadonlySet<string> = new Set([
|
||||
'print',
|
||||
'debugPrint',
|
||||
|
|
@ -257,5 +275,6 @@ export const swiftProvider = defineLanguage({
|
|||
classExtractor: createClassExtractor(swiftClassConfig),
|
||||
heritageExtractor: createHeritageExtractor(SupportedLanguages.Swift),
|
||||
implicitImportWirer: wireSwiftImplicitImports,
|
||||
orderSameNameTypeCandidates: orderSwiftSameNameTypeCandidates,
|
||||
builtInNames: BUILT_INS,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// gitnexus/src/core/ingestion/method-extractors/configs/swift.ts
|
||||
// Verified against tree-sitter-swift 0.6.0
|
||||
// Verified against tree-sitter-swift 0.7.x
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type {
|
||||
|
|
@ -110,7 +110,7 @@ function extractSwiftReturnType(node: SyntaxNode): string | undefined {
|
|||
function extractSwiftParameters(node: SyntaxNode): ParameterInfo[] {
|
||||
const params: ParameterInfo[] = [];
|
||||
|
||||
// In tree-sitter-swift 0.6.0, parameters are direct children of function_declaration.
|
||||
// In tree-sitter-swift, parameters are direct children of function_declaration.
|
||||
// Default value tokens ('=', literal) are siblings of the parameter node at the
|
||||
// function_declaration level, not children of the parameter node.
|
||||
for (let i = 0; i < node.childCount; i++) {
|
||||
|
|
@ -264,8 +264,7 @@ function extractSwiftAnnotations(node: SyntaxNode): string[] {
|
|||
export const swiftMethodConfig: MethodExtractionConfig = {
|
||||
language: SupportedLanguages.Swift,
|
||||
|
||||
// tree-sitter-swift 0.6.0 may use class_declaration for classes, structs, enums, extensions,
|
||||
// and actors — but this cannot be verified until the grammar installs on Node 22+.
|
||||
// Keep this conservative until Swift type-shape coverage is expanded.
|
||||
// TODO: Verify struct_declaration, enum_declaration, extension_declaration, actor_declaration
|
||||
// node types once tree-sitter-swift loads on Node 22, and add them here if they are distinct.
|
||||
// protocol_declaration is a separate, confirmed node type.
|
||||
|
|
|
|||
|
|
@ -542,10 +542,13 @@ const processParsingSequential = async (
|
|||
}
|
||||
}
|
||||
|
||||
// Append #<paramCount> to Method/Constructor IDs to disambiguate overloads.
|
||||
// Functions are not suffixed — they don't overload by name in the same scope.
|
||||
// Append #<paramCount> to owned callable IDs to disambiguate overloads.
|
||||
// Top-level Function IDs stay stable; functions inside an owner may overload.
|
||||
// When same-arity collisions exist, append ~type1,type2 for further disambiguation.
|
||||
const needsAritySuffix = nodeLabel === 'Method' || nodeLabel === 'Constructor';
|
||||
const needsAritySuffix =
|
||||
nodeLabel === 'Method' ||
|
||||
nodeLabel === 'Constructor' ||
|
||||
(nodeLabel === 'Function' && enclosingClassId !== null);
|
||||
let arityTag = needsAritySuffix && arityForId !== undefined ? `#${arityForId}` : '';
|
||||
if (arityTag && seqDefMethods && seqDefMethodInfo && seqClassNodeId !== undefined) {
|
||||
// Use cached method map + collision groups (built once per class, not per method)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ function unwrapSwiftExpression(node: SyntaxNode): SyntaxNode {
|
|||
return node;
|
||||
}
|
||||
|
||||
function swiftNavigationSuffixName(node: SyntaxNode | null): string | undefined {
|
||||
return node?.type === 'navigation_suffix' ? node.lastNamedChild?.text : node?.text;
|
||||
}
|
||||
|
||||
/** Swift: let x: Foo = ... */
|
||||
const extractDeclaration: TypeBindingExtractor = (
|
||||
node: SyntaxNode,
|
||||
|
|
@ -119,8 +123,10 @@ const extractInitializer: InitializerExtractor = (
|
|||
// Explicit init: User.init(name: "alice") — navigation_expression with .init suffix
|
||||
if (callee.type === 'navigation_expression') {
|
||||
const receiver = callee.firstNamedChild;
|
||||
const suffix = callee.lastNamedChild;
|
||||
if (receiver?.type === 'simple_identifier' && suffix?.text === 'init') {
|
||||
if (
|
||||
receiver?.type === 'simple_identifier' &&
|
||||
swiftNavigationSuffixName(callee.lastNamedChild) === 'init'
|
||||
) {
|
||||
const calleeName = receiver.text;
|
||||
if (calleeName && classNames.has(calleeName)) {
|
||||
env.set(varName, calleeName);
|
||||
|
|
@ -133,7 +139,7 @@ const extractInitializer: InitializerExtractor = (
|
|||
const scanConstructorBinding: ConstructorBindingScanner = (node) => {
|
||||
if (node.type !== 'property_declaration') return undefined;
|
||||
if (hasTypeAnnotation(node)) return undefined;
|
||||
const pattern = node.childForFieldName('pattern');
|
||||
const pattern = node.childForFieldName('pattern') ?? findChild(node, 'pattern');
|
||||
if (!pattern) return undefined;
|
||||
const varName = pattern.text;
|
||||
if (!varName) return undefined;
|
||||
|
|
@ -162,7 +168,7 @@ const scanConstructorBinding: ConstructorBindingScanner = (node) => {
|
|||
if (callee.type === 'navigation_expression') {
|
||||
const receiver = callee.firstNamedChild;
|
||||
const suffix = callee.lastNamedChild;
|
||||
if (receiver?.type === 'simple_identifier' && suffix?.text === 'init') {
|
||||
if (receiver?.type === 'simple_identifier' && swiftNavigationSuffixName(suffix) === 'init') {
|
||||
return { varName, calleeName: receiver.text };
|
||||
}
|
||||
// General qualified call: service.getUser() → extract method name.
|
||||
|
|
|
|||
|
|
@ -2078,10 +2078,13 @@ const processFileGroup = (
|
|||
}
|
||||
}
|
||||
|
||||
// Append #<paramCount> to Method/Constructor IDs to disambiguate overloads.
|
||||
// Functions are not suffixed — they don't overload by name in the same scope.
|
||||
// Append #<paramCount> to owned callable IDs to disambiguate overloads.
|
||||
// Top-level Function IDs stay stable; functions inside an owner may overload.
|
||||
// When same-arity collisions exist, append ~type1,type2 for further disambiguation.
|
||||
const needsAritySuffix = nodeLabel === 'Method' || nodeLabel === 'Constructor';
|
||||
const needsAritySuffix =
|
||||
nodeLabel === 'Method' ||
|
||||
nodeLabel === 'Constructor' ||
|
||||
(nodeLabel === 'Function' && enclosingClassId !== null);
|
||||
let arityTag = needsAritySuffix && arityForId !== undefined ? `#${arityForId}` : '';
|
||||
if (arityTag && defMethodMap && defMethodInfo) {
|
||||
const groups = buildCollisionGroups(defMethodMap);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* Verifies that `let user = User(name: "alice"); user.save()` resolves to User.save
|
||||
* without explicit type annotations, using SymbolTable verification.
|
||||
*
|
||||
* NOTE: tree-sitter-swift has build issues on Node 22 — these tests skip gracefully
|
||||
* when the Swift parser is not available.
|
||||
* NOTE: Swift is installed as an optional dependency. These tests skip gracefully
|
||||
* if a consumer installs without optional dependencies.
|
||||
*/
|
||||
import { describe, it, expect, beforeAll } from 'vitest';
|
||||
import path from 'path';
|
||||
|
|
|
|||
|
|
@ -48,6 +48,20 @@ describe('CLI commands', () => {
|
|||
'file:./vendor/tree-sitter-dart',
|
||||
);
|
||||
});
|
||||
|
||||
it('uses the vendored official Swift runtime package instead of source-building on install', async () => {
|
||||
const pkg = await import('../../package.json', { with: { type: 'json' } });
|
||||
const swiftPkg = await import('../../vendor/tree-sitter-swift/package.json', {
|
||||
with: { type: 'json' },
|
||||
});
|
||||
expect(pkg.default.dependencies['tree-sitter']).toBe('^0.21.1');
|
||||
expect(pkg.default.optionalDependencies['tree-sitter-swift']).toBe(
|
||||
'file:./vendor/tree-sitter-swift',
|
||||
);
|
||||
expect(pkg.default.scripts.postinstall).not.toContain('tree-sitter-swift');
|
||||
expect(swiftPkg.default.version).toBe('0.7.1');
|
||||
expect(swiftPkg.default.peerDependencies['tree-sitter']).toContain('^0.21.1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('analyzeCommand', () => {
|
||||
|
|
|
|||
|
|
@ -19,11 +19,8 @@ describe('isLanguageAvailable', () => {
|
|||
expect(isLanguageAvailable('haskell' as SupportedLanguages)).toBe(false);
|
||||
});
|
||||
|
||||
it('handles Swift based on optional dependency availability', () => {
|
||||
// Swift is optional — result depends on whether tree-sitter-swift is installed
|
||||
const result = isLanguageAvailable(SupportedLanguages.Swift);
|
||||
expect(typeof result).toBe('boolean');
|
||||
// Either way, it should not throw
|
||||
it('returns true for Swift in the default install', () => {
|
||||
expect(isLanguageAvailable(SupportedLanguages.Swift)).toBe(true);
|
||||
});
|
||||
|
||||
it('handles Kotlin based on optional dependency availability', () => {
|
||||
|
|
|
|||
|
|
@ -4385,12 +4385,14 @@ class Foo {
|
|||
expect(m.parameters[0]).toEqual({
|
||||
name: 'name',
|
||||
type: 'String',
|
||||
rawType: 'String',
|
||||
isOptional: false,
|
||||
isVariadic: false,
|
||||
});
|
||||
expect(m.parameters[1]).toEqual({
|
||||
name: 'age',
|
||||
type: 'Int',
|
||||
rawType: 'Int',
|
||||
isOptional: true,
|
||||
isVariadic: false,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -81,15 +81,14 @@ describe('parser-loader', () => {
|
|||
});
|
||||
|
||||
describe('Swift optional dependency', () => {
|
||||
it('handles Swift loading gracefully', async () => {
|
||||
// Swift is optional — it either loads successfully or throws an error about unsupported language
|
||||
try {
|
||||
await loadLanguage(SupportedLanguages.Swift);
|
||||
// If it succeeds, tree-sitter-swift is installed
|
||||
} catch (e: any) {
|
||||
// If it fails, it should be because tree-sitter-swift is not installed
|
||||
expect(e.message).toContain('Unsupported language');
|
||||
}
|
||||
it('loads Swift from the default optional dependency and parses source', async () => {
|
||||
const parser = await loadParser();
|
||||
await loadLanguage(SupportedLanguages.Swift);
|
||||
|
||||
const tree = parser.parse('class Foo { func bar() {} }');
|
||||
|
||||
expect(tree.rootNode.type).toBe('source_file');
|
||||
expect(tree.rootNode.namedChildCount).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2895,6 +2895,24 @@ class User : BaseModel<string> {
|
|||
expect(typeEnv.constructorBindings.find((b) => b.varName === 'user')).toBeUndefined();
|
||||
});
|
||||
|
||||
describeSwift('Swift constructor binding scanner', () => {
|
||||
it('returns constructor binding for explicit User.init(...) calls', () => {
|
||||
const tree = parseSwift(`
|
||||
func run() {
|
||||
let user = User.init(name: "alice")
|
||||
}
|
||||
`);
|
||||
const typeEnv = buildTypeEnv(tree, 'swift');
|
||||
expect(flatGet(typeEnv, 'user')).toBeUndefined();
|
||||
expect(typeEnv.constructorBindings).toEqual([
|
||||
expect.objectContaining({
|
||||
varName: 'user',
|
||||
calleeName: 'User',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns constructor bindings for Python x = UnknownClass()', () => {
|
||||
const tree = parse(
|
||||
`
|
||||
|
|
|
|||
21
gitnexus/vendor/tree-sitter-swift/LICENSE
vendored
Normal file
21
gitnexus/vendor/tree-sitter-swift/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 alex-pinkus
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
139
gitnexus/vendor/tree-sitter-swift/README.md
vendored
Normal file
139
gitnexus/vendor/tree-sitter-swift/README.md
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
## GitNexus vendor notice
|
||||
|
||||
This directory is a GitNexus-managed vendored copy of the official
|
||||
`tree-sitter-swift@0.7.1` npm runtime package, including its official native
|
||||
prebuilds. GitNexus keeps the top-level `tree-sitter` dependency pinned to
|
||||
`^0.21.1` until the broader parser runtime upgrade is handled separately.
|
||||
|
||||
When updating this vendor package, replace it from an official
|
||||
`tree-sitter-swift` npm release, keep the native `prebuilds/` artifacts, update
|
||||
the `_vendoredBy` provenance fields in `package.json`, and verify the packed
|
||||
GitNexus tarball can load `tree-sitter-swift`.
|
||||
|
||||

|
||||
[](https://crates.io/crates/tree-sitter-swift)
|
||||
[](https://www.npmjs.com/package/tree-sitter-swift)
|
||||
[](https://github.com/alex-pinkus/tree-sitter-swift/actions/workflows/top-repos.yml)
|
||||
|
||||
# tree-sitter-swift
|
||||
|
||||
This contains a [`tree-sitter`](https://tree-sitter.github.io/tree-sitter) grammar for the Swift programming language.
|
||||
|
||||
## Getting started
|
||||
|
||||
To use this parser to parse Swift code, you'll want to depend on either the Rust crate or the NPM package.
|
||||
|
||||
### Rust
|
||||
|
||||
To use the Rust crate, you'll add this to your `Cargo.toml`:
|
||||
|
||||
```
|
||||
tree-sitter = "0.23.0"
|
||||
tree-sitter-swift = "=0.7.0"
|
||||
```
|
||||
|
||||
Then you can use a `tree-sitter` parser with the language declared here:
|
||||
|
||||
```
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
parser.set_language(tree_sitter_swift::language())?;
|
||||
|
||||
// ...
|
||||
|
||||
let tree = parser.parse(&my_source_code, None)
|
||||
.ok_or_else(|| /* error handling code */)?;
|
||||
```
|
||||
|
||||
### Javascript
|
||||
|
||||
To use this from NPM, you'll add similar dependencies to `package.json`:
|
||||
|
||||
```
|
||||
"dependencies: {
|
||||
"tree-sitter-swift": "0.7.0",
|
||||
"tree-sitter": "^0.22.1"
|
||||
}
|
||||
```
|
||||
|
||||
Your usage of the parser will look like:
|
||||
|
||||
```
|
||||
const Parser = require("tree-sitter");
|
||||
const Swift = require("tree-sitter-swift");
|
||||
|
||||
const parser = new Parser();
|
||||
parser.setLanguage(Swift);
|
||||
|
||||
// ...
|
||||
|
||||
const tree = parser.parse(mySourceCode);
|
||||
```
|
||||
|
||||
### Editing the grammar
|
||||
|
||||
With this package checked out, a common workflow for editing the grammar will look something like:
|
||||
|
||||
1. Make a change to `grammar.ts`.
|
||||
2. Run `npm install && npm test` to see whether the change has had impact on existing parsing behavior. The default
|
||||
`npm test` target requires `valgrind` to be installed; if you do not have it installed, and do not wish to, you can
|
||||
substitute `tree-sitter test` directly.
|
||||
3. Run `tree-sitter parse` on some real Swift codebase and see whether (or where) it fails.
|
||||
4. Use any failures to create new corpus test cases.
|
||||
|
||||
## Contributions
|
||||
|
||||
All contributions to this repository are welcome.
|
||||
|
||||
If said contribution is to check generated files (e.g., `parser.c`) into the repository, be aware that your contribution will not be accepted. Make sure to read the [FAQ entry](https://github.com/alex-pinkus/tree-sitter-swift?tab=readme-ov-file#where-is-your-parserc) and the [prior](https://github.com/alex-pinkus/tree-sitter-swift/issues/362) [discussions](https://github.com/alex-pinkus/tree-sitter-swift/pull/315) and [compromises](https://github.com/alex-pinkus/tree-sitter-swift/issues/149) that have occurred already on this topic.
|
||||
|
||||
## Using tree-sitter-swift in Web Assembly
|
||||
|
||||
To use tree-sitter-swift as a language for the web bindings version tree-sitter, which will likely be a more modern version than the published node
|
||||
module. [see](https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/README.md). Follow the instructions below
|
||||
|
||||
1. Install the node modules `npm install web-tree-sitter tree-sitter-swift`
|
||||
2. Run the tree-sitter cli to create the wasm bundle
|
||||
```sh
|
||||
$ npx tree-sitter build-asm ./node_modules/tree-sitter
|
||||
```
|
||||
3. Boot tree-sitter wasm like this.
|
||||
|
||||
```js
|
||||
const Parser = require('web-tree-sitter');
|
||||
async function run() {
|
||||
//needs to happen first
|
||||
await Parser.init();
|
||||
//wait for the load of swift
|
||||
const Swift = await Parser.Language.load('./tree-sitter-swift.wasm');
|
||||
|
||||
const parser = new Parser();
|
||||
parser.setLanguage(Swift);
|
||||
|
||||
//Parse your swift code here.
|
||||
const tree = parser.parse('print("Hello, World!")');
|
||||
}
|
||||
//if you want to run this
|
||||
run().then(console.log, console.error);
|
||||
```
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
### Where is your `parser.c`?
|
||||
|
||||
This repository currently omits most of the code that is autogenerated during a build. This means, for instance, that
|
||||
`grammar.json` and `parser.c` are both only available following a build. It also significantly reduces noise during
|
||||
diffs.
|
||||
|
||||
The side benefit of not checking in `parser.c` is that you can guarantee backwards compatibility. Parsers generated by
|
||||
the tree-sitter CLI aren't always backwards compatible. If you need a parser, generate it yourself using the CLI; all
|
||||
the information to do so is available in this package. By doing that, you'll also know for sure that your parser version
|
||||
and your library version are compatible.
|
||||
|
||||
If you need a `parser.c`, and you don't care about the tree-sitter version, but you don't have a local setup that would
|
||||
allow you to obtain the parser, you can just download one from a recent workflow run in this package. To do so:
|
||||
|
||||
- Go to the [GitHub actions page](https://github.com/alex-pinkus/tree-sitter-swift/actions) for this
|
||||
repository.
|
||||
- Click on the "Publish `grammar.json` and `parser.c`" action for the appropriate commit.
|
||||
- Go down to `Artifacts` and click on `generated-parser-src`. All the relevant parser files will be available in your
|
||||
download.
|
||||
28
gitnexus/vendor/tree-sitter-swift/bindings/node/index.d.ts
vendored
Normal file
28
gitnexus/vendor/tree-sitter-swift/bindings/node/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
type BaseNode = {
|
||||
type: string;
|
||||
named: boolean;
|
||||
};
|
||||
|
||||
type ChildNode = {
|
||||
multiple: boolean;
|
||||
required: boolean;
|
||||
types: BaseNode[];
|
||||
};
|
||||
|
||||
type NodeInfo =
|
||||
| (BaseNode & {
|
||||
subtypes: BaseNode[];
|
||||
})
|
||||
| (BaseNode & {
|
||||
fields: { [name: string]: ChildNode };
|
||||
children: ChildNode[];
|
||||
});
|
||||
|
||||
type Language = {
|
||||
name: string;
|
||||
language: unknown;
|
||||
nodeTypeInfo: NodeInfo[];
|
||||
};
|
||||
|
||||
declare const language: Language;
|
||||
export = language;
|
||||
7
gitnexus/vendor/tree-sitter-swift/bindings/node/index.js
vendored
Normal file
7
gitnexus/vendor/tree-sitter-swift/bindings/node/index.js
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const root = require("path").join(__dirname, "..", "..");
|
||||
|
||||
module.exports = require("node-gyp-build")(root);
|
||||
|
||||
try {
|
||||
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
||||
} catch (_) {}
|
||||
28
gitnexus/vendor/tree-sitter-swift/package.json
vendored
Normal file
28
gitnexus/vendor/tree-sitter-swift/package.json
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "tree-sitter-swift",
|
||||
"version": "0.7.1",
|
||||
"description": "A tree-sitter grammar for the Swift programming language",
|
||||
"main": "bindings/node/index.js",
|
||||
"types": "bindings/node/index.d.ts",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/alex-pinkus/tree-sitter-swift.git"
|
||||
},
|
||||
"_vendoredBy": "gitnexus - minimal runtime package copied from official tree-sitter-swift@0.7.1 (gitHead 88bfd19a89be9d0481b14566fb6160cccea2fe0a). Keeps upstream prebuilds while allowing GitNexus to stay on tree-sitter@0.21.1 until #858 is resolved.",
|
||||
"scripts": {
|
||||
"install": "node-gyp-build"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-addon-api": "^8.0.0",
|
||||
"node-gyp-build": "^4.8.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.21.1 || ^0.22.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree-sitter": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/darwin-arm64/tree-sitter-swift.node
vendored
Normal file
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/darwin-arm64/tree-sitter-swift.node
vendored
Normal file
Binary file not shown.
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/darwin-x64/tree-sitter-swift.node
vendored
Normal file
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/darwin-x64/tree-sitter-swift.node
vendored
Normal file
Binary file not shown.
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/linux-arm64/tree-sitter-swift.node
vendored
Normal file
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/linux-arm64/tree-sitter-swift.node
vendored
Normal file
Binary file not shown.
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/linux-x64/tree-sitter-swift.node
vendored
Normal file
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/linux-x64/tree-sitter-swift.node
vendored
Normal file
Binary file not shown.
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/win32-arm64/tree-sitter-swift.node
vendored
Normal file
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/win32-arm64/tree-sitter-swift.node
vendored
Normal file
Binary file not shown.
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/win32-x64/tree-sitter-swift.node
vendored
Normal file
BIN
gitnexus/vendor/tree-sitter-swift/prebuilds/win32-x64/tree-sitter-swift.node
vendored
Normal file
Binary file not shown.
30694
gitnexus/vendor/tree-sitter-swift/src/node-types.json
vendored
Normal file
30694
gitnexus/vendor/tree-sitter-swift/src/node-types.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue