mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-06 02:49:56 +00:00
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
This commit is contained in:
parent
780ee83d52
commit
cf3df472b1
25 changed files with 31011 additions and 170 deletions
|
|
@ -3,7 +3,6 @@ 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 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',
|
||||
);
|
||||
}
|
||||
|
|
@ -1617,19 +1617,27 @@ const disambiguateByOverloadOrArgTypes = (
|
|||
* 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.
|
||||
* Used by free-call, constructor, and member-call paths. Having a single
|
||||
* source of truth prevents duplication if the heuristic is ever tuned.
|
||||
*/
|
||||
const dedupSwiftExtensionCandidates = (
|
||||
candidates: readonly SymbolDefinition[],
|
||||
tier: ResolutionTier,
|
||||
): ResolveResult | null => {
|
||||
const sorted = orderSwiftExtensionCandidates(candidates);
|
||||
return sorted ? toResolveResult(sorted[0], tier) : null;
|
||||
};
|
||||
|
||||
const orderSwiftExtensionCandidates = (
|
||||
candidates: readonly SymbolDefinition[],
|
||||
): SymbolDefinition[] | 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);
|
||||
return [...candidates].sort(
|
||||
(a, b) => a.filePath.length - b.filePath.length || a.filePath.localeCompare(b.filePath),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2223,6 +2231,33 @@ const resolveMethodByOwner = (
|
|||
}
|
||||
}
|
||||
|
||||
if (!firstDef && !ambiguous) {
|
||||
const extensionCandidates = orderSwiftExtensionCandidates(
|
||||
ctx.model.types.lookupClassByName(receiverTypeName),
|
||||
);
|
||||
if (extensionCandidates) {
|
||||
for (const candidate of extensionCandidates) {
|
||||
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 };
|
||||
};
|
||||
|
|
@ -2563,6 +2598,8 @@ export const resolveStaticCall = (
|
|||
// homonym classes across files with no import narrowing). Fall through
|
||||
// to `return null` so the caller null-routes rather than guess.
|
||||
if (instantiableCandidates.length === 1) {
|
||||
const primary = orderSwiftExtensionCandidates(allClasses);
|
||||
if (primary) return toResolveResult(primary[0], typeResolved.tier);
|
||||
return toResolveResult(instantiableCandidates[0], typeResolved.tier);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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', () => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
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.
|
||||
127
gitnexus/vendor/tree-sitter-swift/README.md
vendored
Normal file
127
gitnexus/vendor/tree-sitter-swift/README.md
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||

|
||||
[](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