mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-03 02:21:44 +00:00
* docs: add Objective-C fork provider notes * feat(objective-c): add deterministic provider and grammar * feat(objective-c): finalize provider MVP * fix(objective-c): harden provider integration * fix(objective-c): normalize bare macro markers * docs(objective-c): integrate provider documentation * fix(objective-c): harden resolution and header classification * fix(objective-c): complete provider follow-ups * fix: address Objective-C review follow-ups * chore: format Objective-C grammar sources * fix(objective-c): harden review follow-ups * Address PR review feedback (#3179) Keep Objective-C chunking and macro recovery aligned with the grammar, and stop Community MEMBER_OF edges from leaking into symbol context. Co-authored-by: Cursor <cursoragent@cursor.com> * Address follow-up review on ObjC chunking and language fallback. Keep preprocessor directive text from changing file-scope brace depth, group real ivar nodes, skip header modifiers, and restore Rakefile/Gemfile detection through getLanguageFromFilename. Co-authored-by: Cursor <cursoragent@cursor.com> * Parse Objective-C headers with the objc grammar in embeddings. ensureAndParse and structural extraction now use the same content classifier as ingest, including method snippets from .h files, so Protocol/Category/Class chunks are not re-parsed as C++. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3179) Keep file-scope macro elision off C line splices and @interface/@protocol/@implementation bodies, and attach ivar attributes to the following instance variable when chunking. Co-authored-by: Cursor <cursoragent@cursor.com> * chore(bench): rebaseline Objective-C CSV emit * feat(objective-c): add workspace resolution and linear emit benches Plain .h files are classified as C++, so the ObjC pass could not resolve #import of those headers. Load a C/C#-style workspace once per pass, and keep protocol-candidate USES linear. Refs #3179 Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3179) - Compare LadybugDB labels() as a scalar when excluding Community MEMBER_OF edges. - Walk superclass members, skip file-static C sibling defs, and ignore comments in ObjC header/macro scans. Note: pre-existing failure in objective-c-provider integration (worker-pool ready timeout) not addressed by this PR. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3179) Emit Objective-C declaration captures so compilation-unit siblings can share header/implementation bindings, and keep class vs protocol visibility groups distinct. Note: pre-existing failure in worker-pool startup (GITNEXUS_WORKER_READY_TIMEOUT_MS) not addressed by this PR. Co-authored-by: Cursor <cursoragent@cursor.com> * Address PR review feedback (#3179) Emit every comma-separated property/ivar declarator, and count @interface after a multiline block comment closes so in-declaration macros stay intact. Note: pre-existing failure in worker-pool startup (GITNEXUS_WORKER_READY_TIMEOUT_MS) not addressed by this PR. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: ximengkai <ximengkai@soyoung.com> Co-authored-by: Gergő Magyar <gergomagyar@icloud.com> Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
128 lines
5.1 KiB
JavaScript
128 lines
5.1 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Activate the vendored tree-sitter native bindings IN PLACE under `vendor/`.
|
|
* One registry-driven script replaces the former per-grammar
|
|
* build-tree-sitter-<name>.cjs files (they were ~95% identical).
|
|
*
|
|
* The grammars (tree-sitter-c/objc/dart/proto/swift/kotlin/zig) are loaded from
|
|
* `vendor/<name>/` by absolute path at runtime (see
|
|
* src/core/tree-sitter/vendored-grammars.ts) and are NEVER copied into
|
|
* node_modules — an undeclared package under node_modules is "extraneous" to
|
|
* every subsequent npm/npx reify, which prunes/relocates it (Windows
|
|
* `EPERM: …, symlink` + a silent grammar deletion on the 2nd run; #2111/#1728).
|
|
*
|
|
* For each grammar the resolution order is identical:
|
|
* 1. If the vendored source is absent (no binding.gyp) or the binding is
|
|
* already built, do nothing.
|
|
* 2. Prefer a committed prebuild for this platform-arch (toolchain-free) via
|
|
* node-gyp-build — `vendor/<name>/prebuilds/` ships all six tuples, so on a
|
|
* supported platform this returns immediately and writes nothing.
|
|
* 3. Otherwise source-build from the vendored grammar source (binding.gyp +
|
|
* src/) into `vendor/<name>/build/` (gitignored) so parsing still works on
|
|
* a toolchain host that lacks a matching prebuild.
|
|
*
|
|
* HARD INVARIANT: this runs in `gitnexus`'s postinstall, so it MUST NEVER throw
|
|
* or exit non-zero — a failure for any single grammar must not break the install.
|
|
*
|
|
* Opt-out: GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1 (strict '1') skips the OPTIONAL
|
|
* grammars only. tree-sitter-c and tree-sitter-objc are REQUIRED (C backstops upstream's 4/6 ARM
|
|
* prebuild gap, #2116) and are always built.
|
|
*
|
|
* Usage:
|
|
* node build-tree-sitter-grammars.cjs # all grammars (postinstall)
|
|
* node build-tree-sitter-grammars.cjs swift c # only the named grammars
|
|
*/
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { execSync } = require('child_process');
|
|
|
|
// Registry. `display`/`ext` drive the human-readable warnings; `required`
|
|
// grammars ignore the opt-out gate. Insertion order == build order (c first).
|
|
const GRAMMARS = {
|
|
c: { required: true, display: 'C', ext: '.c' },
|
|
objc: { required: true, display: 'Objective-C', ext: '.m/.mm/.h' },
|
|
dart: { required: false, display: 'Dart', ext: '.dart' },
|
|
proto: { required: false, display: 'Proto', ext: '.proto' },
|
|
swift: { required: false, display: 'Swift', ext: '.swift' },
|
|
kotlin: { required: false, display: 'Kotlin', ext: '.kt/.kts' },
|
|
zig: { required: false, display: 'Zig', ext: '.zig' },
|
|
};
|
|
|
|
const skipOptional = process.env.GITNEXUS_SKIP_OPTIONAL_GRAMMARS === '1';
|
|
|
|
function buildGrammar(short) {
|
|
const cfg = GRAMMARS[short];
|
|
const tag = `[tree-sitter-${short}]`;
|
|
|
|
if (!cfg.required && skipOptional) {
|
|
console.warn(
|
|
`${tag} Skipping build (GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1). ${cfg.display} parsing will be unavailable until reinstalled without the env var.`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
const dir = path.join(__dirname, '..', 'vendor', `tree-sitter-${short}`);
|
|
const bindingGyp = path.join(dir, 'binding.gyp');
|
|
const bindingNode = path.join(dir, 'build', 'Release', `tree_sitter_${short}_binding.node`);
|
|
|
|
try {
|
|
// Not materialized (no source), or already built — nothing to do.
|
|
if (!fs.existsSync(bindingGyp) || fs.existsSync(bindingNode)) {
|
|
return;
|
|
}
|
|
|
|
// Prefer a committed prebuild for this platform-arch (no toolchain needed).
|
|
try {
|
|
require('node-gyp-build').path(dir);
|
|
return;
|
|
} catch {
|
|
// No matching prebuild — fall through to the source build below.
|
|
}
|
|
|
|
// The hoisted build deps must be resolvable to source-build.
|
|
try {
|
|
require.resolve('node-addon-api');
|
|
require.resolve('node-gyp-build');
|
|
} catch (resolveErr) {
|
|
console.warn(
|
|
`${tag} Skipping build: hoisted build deps not resolvable (${resolveErr.message}).`,
|
|
);
|
|
console.warn(
|
|
`${tag} ${cfg.display} parsing will be unavailable until a prebuild or toolchain is present.`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
console.log(`${tag} No prebuild for this platform — building native binding from source...`);
|
|
execSync('npx node-gyp rebuild', { cwd: dir, stdio: 'pipe', timeout: 180000 });
|
|
console.log(`${tag} Native binding built successfully`);
|
|
} catch (err) {
|
|
console.warn(`${tag} Could not build native binding:`, err.message);
|
|
console.warn(
|
|
`${tag} ${cfg.display} (${cfg.ext}) parsing will be unavailable. Non-${cfg.display} functionality is unaffected.`,
|
|
);
|
|
}
|
|
}
|
|
|
|
function main() {
|
|
const args = process.argv.slice(2).filter(Boolean);
|
|
const targets = args.length > 0 ? args : Object.keys(GRAMMARS);
|
|
for (const short of targets) {
|
|
if (!GRAMMARS[short]) {
|
|
console.warn(`[tree-sitter] Unknown grammar '${short}' — skipping.`);
|
|
continue;
|
|
}
|
|
// Defensive: never let an unexpected throw escape and fail the install.
|
|
try {
|
|
buildGrammar(short);
|
|
} catch (err) {
|
|
console.warn(`[tree-sitter-${short}] Unexpected build error (ignored): ${err.message}`);
|
|
}
|
|
}
|
|
// Hard guarantee: postinstall must never exit non-zero.
|
|
process.exit(0);
|
|
}
|
|
|
|
if (require.main === module) main();
|
|
|
|
module.exports = { GRAMMARS, buildGrammar };
|