gitnexus 1.6.12-rc.2 → 1.6.12-rc.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/dist/_shared/graph/types.d.ts +1 -1
  2. package/dist/_shared/graph/types.d.ts.map +1 -1
  3. package/dist/_shared/language-detection.d.ts.map +1 -1
  4. package/dist/_shared/language-detection.js +2 -0
  5. package/dist/_shared/language-detection.js.map +1 -1
  6. package/dist/_shared/languages.d.ts +1 -0
  7. package/dist/_shared/languages.d.ts.map +1 -1
  8. package/dist/_shared/languages.js +1 -0
  9. package/dist/_shared/languages.js.map +1 -1
  10. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  11. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  12. package/dist/_shared/lbug/schema-constants.js +2 -0
  13. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  14. package/dist/_shared/scope-resolution/language-classification.d.ts +2 -1
  15. package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
  16. package/dist/_shared/scope-resolution/language-classification.js +3 -1
  17. package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
  18. package/dist/_shared/scope-resolution/registries/class-registry.d.ts +3 -3
  19. package/dist/_shared/scope-resolution/registries/class-registry.js +3 -3
  20. package/dist/_shared/scope-resolution/registries/context.d.ts.map +1 -1
  21. package/dist/_shared/scope-resolution/registries/context.js +2 -0
  22. package/dist/_shared/scope-resolution/registries/context.js.map +1 -1
  23. package/dist/_shared/scope-resolution/resolve-type-ref.d.ts.map +1 -1
  24. package/dist/_shared/scope-resolution/resolve-type-ref.js +2 -0
  25. package/dist/_shared/scope-resolution/resolve-type-ref.js.map +1 -1
  26. package/dist/cli/analyze-config.d.ts +2 -2
  27. package/dist/cli/analyze-config.js +10 -33
  28. package/dist/cli/doctor.js +6 -4
  29. package/dist/cli/eval-server.js +13 -1
  30. package/dist/cli/i18n/en.d.ts +4 -2
  31. package/dist/cli/i18n/en.js +4 -2
  32. package/dist/cli/i18n/resources.d.ts +6 -2
  33. package/dist/cli/i18n/zh-CN.d.ts +2 -0
  34. package/dist/cli/i18n/zh-CN.js +4 -2
  35. package/dist/core/analysis-feature-registry.d.ts +1 -1
  36. package/dist/core/analysis-feature-registry.js +2 -0
  37. package/dist/core/auto-sync/starter.js +2 -2
  38. package/dist/core/embeddings/ast-utils.js +8 -3
  39. package/dist/core/embeddings/chunker.js +67 -10
  40. package/dist/core/embeddings/embedding-pipeline.d.ts +1 -1
  41. package/dist/core/embeddings/embedding-pipeline.js +1 -1
  42. package/dist/core/embeddings/structural-extractor.js +2 -2
  43. package/dist/core/embeddings/types.d.ts +4 -2
  44. package/dist/core/embeddings/types.js +18 -0
  45. package/dist/core/git-ref.d.ts +22 -0
  46. package/dist/core/git-ref.js +114 -0
  47. package/dist/core/git-staleness.js +14 -0
  48. package/dist/core/group/extractors/graphql-extractor.d.ts +1 -1
  49. package/dist/core/group/extractors/graphql-extractor.js +149 -13
  50. package/dist/core/group/extractors/manifest-extractor.d.ts +1 -1
  51. package/dist/core/group/extractors/manifest-extractor.js +2 -2
  52. package/dist/core/ingestion/call-extractors/zig-static-gating.d.ts +5 -8
  53. package/dist/core/ingestion/content-language-classification.d.ts +10 -0
  54. package/dist/core/ingestion/content-language-classification.js +30 -0
  55. package/dist/core/ingestion/filesystem-walker.d.ts +1 -0
  56. package/dist/core/ingestion/filesystem-walker.js +1 -1
  57. package/dist/core/ingestion/import-resolvers/node-workspace-packages.js +3 -2
  58. package/dist/core/ingestion/language-config.d.ts +82 -13
  59. package/dist/core/ingestion/language-config.js +217 -13
  60. package/dist/core/ingestion/language-provider.d.ts +88 -1
  61. package/dist/core/ingestion/languages/index.d.ts +7 -0
  62. package/dist/core/ingestion/languages/index.js +30 -1
  63. package/dist/core/ingestion/languages/objective-c/analysis-features.d.ts +10 -0
  64. package/dist/core/ingestion/languages/objective-c/analysis-features.js +19 -0
  65. package/dist/core/ingestion/languages/objective-c/compilation-unit-siblings.d.ts +13 -0
  66. package/dist/core/ingestion/languages/objective-c/compilation-unit-siblings.js +124 -0
  67. package/dist/core/ingestion/languages/objective-c/facts.d.ts +148 -0
  68. package/dist/core/ingestion/languages/objective-c/facts.js +1150 -0
  69. package/dist/core/ingestion/languages/objective-c/import-target.d.ts +11 -0
  70. package/dist/core/ingestion/languages/objective-c/import-target.js +122 -0
  71. package/dist/core/ingestion/languages/objective-c/macro-marker-preprocess.d.ts +24 -0
  72. package/dist/core/ingestion/languages/objective-c/macro-marker-preprocess.js +261 -0
  73. package/dist/core/ingestion/languages/objective-c/resolution-config.d.ts +41 -0
  74. package/dist/core/ingestion/languages/objective-c/resolution-config.js +282 -0
  75. package/dist/core/ingestion/languages/objective-c/scope-resolver.d.ts +2 -0
  76. package/dist/core/ingestion/languages/objective-c/scope-resolver.js +503 -0
  77. package/dist/core/ingestion/languages/objective-c.d.ts +2 -0
  78. package/dist/core/ingestion/languages/objective-c.js +300 -0
  79. package/dist/core/ingestion/languages/typescript/query.d.ts +31 -0
  80. package/dist/core/ingestion/languages/typescript/query.js +7 -1
  81. package/dist/core/ingestion/languages/typescript/tsconfig.js +3 -2
  82. package/dist/core/ingestion/languages/typescript.js +1 -1
  83. package/dist/core/ingestion/languages/zig/query.d.ts +26 -0
  84. package/dist/core/ingestion/languages/zig/query.js +61 -1
  85. package/dist/core/ingestion/languages/zig/range-binding.d.ts +8 -0
  86. package/dist/core/ingestion/languages/zig/range-binding.js +24 -0
  87. package/dist/core/ingestion/languages/zig/scope-resolver.d.ts +3 -2
  88. package/dist/core/ingestion/languages/zig/scope-resolver.js +18 -5
  89. package/dist/core/ingestion/languages/zig/this-alias-bindings.d.ts +58 -0
  90. package/dist/core/ingestion/languages/zig/this-alias-bindings.js +176 -0
  91. package/dist/core/ingestion/languages/zig/workspace-static-gating.d.ts +8 -0
  92. package/dist/core/ingestion/languages/zig/workspace-static-gating.js +82 -0
  93. package/dist/core/ingestion/model/registration-table.d.ts +3 -3
  94. package/dist/core/ingestion/model/registration-table.js +9 -5
  95. package/dist/core/ingestion/model/symbol-table.d.ts +1 -1
  96. package/dist/core/ingestion/model/symbol-table.js +2 -0
  97. package/dist/core/ingestion/model/type-registry.d.ts +1 -1
  98. package/dist/core/ingestion/parsing-processor.d.ts +22 -6
  99. package/dist/core/ingestion/parsing-processor.js +39 -20
  100. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +9 -1
  101. package/dist/core/ingestion/pipeline-phases/parse-impl.js +307 -96
  102. package/dist/core/ingestion/pipeline-phases/parse-round-budget.d.ts +42 -0
  103. package/dist/core/ingestion/pipeline-phases/parse-round-budget.js +50 -0
  104. package/dist/core/ingestion/pipeline-phases/parse.d.ts +7 -1
  105. package/dist/core/ingestion/scope-extractor.js +4 -0
  106. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +13 -0
  107. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +2 -0
  108. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +2 -0
  109. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +78 -5
  110. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +262 -7
  111. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +5 -2
  112. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
  113. package/dist/core/ingestion/scope-resolution/pipeline/run.js +10 -1
  114. package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +39 -3
  115. package/dist/core/ingestion/scope-resolution/scope/walkers.js +82 -3
  116. package/dist/core/ingestion/scope-resolution/value-ref-edges.d.ts +14 -0
  117. package/dist/core/ingestion/scope-resolution/value-ref-edges.js +14 -0
  118. package/dist/core/ingestion/tree-sitter-queries.js +2 -0
  119. package/dist/core/ingestion/utils/symbol-labels.js +2 -0
  120. package/dist/core/ingestion/workers/parse-worker.d.ts +1 -1
  121. package/dist/core/ingestion/workers/parse-worker.js +63 -3
  122. package/dist/core/ingestion/workers/worker-pool.d.ts +56 -2
  123. package/dist/core/ingestion/workers/worker-pool.js +117 -26
  124. package/dist/core/lbug/csv-generator.js +2 -0
  125. package/dist/core/lbug/schema.d.ts +3 -1
  126. package/dist/core/lbug/schema.js +27 -0
  127. package/dist/core/search/fts-indexes.js +13 -4
  128. package/dist/core/search/fts-schema.js +2 -0
  129. package/dist/core/tree-sitter/parser-loader.js +10 -0
  130. package/dist/core/tree-sitter/vendored-grammars.d.ts +1 -1
  131. package/dist/core/tree-sitter/vendored-grammars.js +2 -1
  132. package/dist/mcp/local/local-backend.d.ts +33 -0
  133. package/dist/mcp/local/local-backend.js +166 -5
  134. package/dist/mcp/tools.js +6 -4
  135. package/dist/server/analyze-job.d.ts +19 -1
  136. package/dist/server/analyze-job.js +14 -3
  137. package/dist/server/analyze-launch.d.ts +14 -0
  138. package/dist/server/analyze-launch.js +59 -14
  139. package/dist/server/analyze-worker-ipc.d.ts +6 -5
  140. package/dist/server/analyze-worker-ipc.js +4 -0
  141. package/dist/server/api.js +68 -21
  142. package/dist/server/git-clone.d.ts +38 -5
  143. package/dist/server/git-clone.js +216 -38
  144. package/dist/server/repo-projection.d.ts +88 -0
  145. package/dist/server/repo-projection.js +53 -0
  146. package/dist/storage/file-lock.js +5 -3
  147. package/dist/storage/parse-cache.js +32 -1
  148. package/dist/storage/parsedfile-store.js +53 -1
  149. package/dist/storage/v8-sidecar.d.ts +11 -0
  150. package/dist/storage/v8-sidecar.js +15 -7
  151. package/dist/utils/process-identity.d.ts +13 -0
  152. package/dist/utils/process-identity.js +18 -0
  153. package/package.json +1 -1
  154. package/scripts/build-tree-sitter-grammars.cjs +4 -3
  155. package/vendor/tree-sitter-objc/LICENSE +21 -0
  156. package/vendor/tree-sitter-objc/README.md +18 -0
  157. package/vendor/tree-sitter-objc/binding.gyp +35 -0
  158. package/vendor/tree-sitter-objc/bindings/node/binding.cc +19 -0
  159. package/vendor/tree-sitter-objc/bindings/node/binding_test.js +9 -0
  160. package/vendor/tree-sitter-objc/bindings/node/index.d.ts +27 -0
  161. package/vendor/tree-sitter-objc/bindings/node/index.js +11 -0
  162. package/vendor/tree-sitter-objc/grammar.js +1286 -0
  163. package/vendor/tree-sitter-objc/package.json +56 -0
  164. package/vendor/tree-sitter-objc/prebuilds/SHA256SUMS +6 -0
  165. package/vendor/tree-sitter-objc/prebuilds/darwin-arm64/tree-sitter-objc.node +0 -0
  166. package/vendor/tree-sitter-objc/prebuilds/darwin-x64/tree-sitter-objc.node +0 -0
  167. package/vendor/tree-sitter-objc/prebuilds/linux-arm64/tree-sitter-objc.node +0 -0
  168. package/vendor/tree-sitter-objc/prebuilds/linux-x64/tree-sitter-objc.node +0 -0
  169. package/vendor/tree-sitter-objc/prebuilds/win32-arm64/tree-sitter-objc.node +0 -0
  170. package/vendor/tree-sitter-objc/prebuilds/win32-x64/tree-sitter-objc.node +0 -0
  171. package/vendor/tree-sitter-objc/queries/folds.scm +20 -0
  172. package/vendor/tree-sitter-objc/queries/highlights.scm +216 -0
  173. package/vendor/tree-sitter-objc/queries/indents.scm +1 -0
  174. package/vendor/tree-sitter-objc/queries/injections.scm +10 -0
  175. package/vendor/tree-sitter-objc/queries/locals.scm +1 -0
  176. package/vendor/tree-sitter-objc/src/grammar.json +16292 -0
  177. package/vendor/tree-sitter-objc/src/node-types.json +7524 -0
  178. package/vendor/tree-sitter-objc/src/parser.c +684023 -0
  179. package/vendor/tree-sitter-objc/src/tree_sitter/alloc.h +54 -0
  180. package/vendor/tree-sitter-objc/src/tree_sitter/array.h +291 -0
  181. package/vendor/tree-sitter-objc/src/tree_sitter/parser.h +266 -0
  182. package/vendor/tree-sitter-objc/tree-sitter-objc.wasm +0 -0
  183. package/vendor/tree-sitter-objc/tree-sitter.json +38 -0
  184. package/web/assets/{agent-BMRqXorA.js → agent-C2n33ANd.js} +1 -1
  185. package/web/assets/{index-Dj3vQOHK.js → index-CHJoW_P1.js} +18 -18
  186. package/web/assets/src-jc8Ffy3T.js +1 -0
  187. package/web/index.html +2 -2
  188. package/web/assets/src-Df5C1Nz4.js +0 -1
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Resolve an Objective-C `#import` / `#include` / `@import` to a workspace file.
3
+ *
4
+ * Quoted imports keep the suffix-index first-path tie-break used before the
5
+ * workspace config existed. Angle-bracket imports never suffix-match the
6
+ * source tree — they only hit in-repo frameworks and HEADER_SEARCH_PATHS —
7
+ * so `<Foundation/Foundation.h>` stays unresolved even when a decoy
8
+ * `Foundation.h` exists. `@import` names resolve only through a scanned
9
+ * module map.
10
+ */
11
+ export declare function resolveObjectiveCImportTarget(targetRaw: string, fromFile: string, allFilePaths: ReadonlySet<string>, resolutionConfig?: unknown): string | null;
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Resolve an Objective-C `#import` / `#include` / `@import` to a workspace file.
3
+ *
4
+ * Quoted imports keep the suffix-index first-path tie-break used before the
5
+ * workspace config existed. Angle-bracket imports never suffix-match the
6
+ * source tree — they only hit in-repo frameworks and HEADER_SEARCH_PATHS —
7
+ * so `<Foundation/Foundation.h>` stays unresolved even when a decoy
8
+ * `Foundation.h` exists. `@import` names resolve only through a scanned
9
+ * module map.
10
+ */
11
+ import path from 'path';
12
+ import { perFileSet } from '../../import-resolvers/per-file-set.js';
13
+ import { coerceObjectiveCResolutionConfig, normalizeRepoPath, } from './resolution-config.js';
14
+ /**
15
+ * Per-pass memo of `allFilePaths ∪ scanned headers`. Identity is load-bearing
16
+ * for `getObjectiveCImportIndex` (same rule as C/C++ `augmentedFilePathsFor`).
17
+ * This memo stays private to Objective-C — sharing it with C would hand each
18
+ * language the other's suffix index.
19
+ */
20
+ const augmentedFilePathsFor = perFileSet((allFilePaths) => perFileSet((headerPaths) => {
21
+ const set = new Set(allFilePaths);
22
+ for (const header of headerPaths)
23
+ set.add(header);
24
+ return set;
25
+ }));
26
+ const getObjectiveCImportIndex = perFileSet((allFilePaths) => {
27
+ const filePaths = [...allFilePaths];
28
+ const suffixMatches = new Map();
29
+ for (const [order, filePath] of filePaths.entries()) {
30
+ const segments = normalizeRepoPath(filePath).split('/');
31
+ for (let start = 1; start < segments.length; start++) {
32
+ const suffix = segments.slice(start).join('/');
33
+ if (!suffixMatches.has(suffix))
34
+ suffixMatches.set(suffix, { filePath, order });
35
+ }
36
+ }
37
+ return { filePathSet: new Set(filePaths), suffixMatches };
38
+ });
39
+ export function resolveObjectiveCImportTarget(targetRaw, fromFile, allFilePaths, resolutionConfig) {
40
+ const target = targetRaw.trim();
41
+ if (target.length === 0)
42
+ return null;
43
+ const config = coerceObjectiveCResolutionConfig(resolutionConfig);
44
+ const searchPaths = config !== undefined && config.headers.size > 0
45
+ ? augmentedFilePathsFor(allFilePaths)(config.headers)
46
+ : allFilePaths;
47
+ if (target.startsWith('<') && target.endsWith('>')) {
48
+ return resolveAngleImport(target.slice(1, -1), searchPaths, config);
49
+ }
50
+ const looksLikeFileImport = target.startsWith('.') || target.includes('/') || path.posix.extname(target).length > 0;
51
+ if (!looksLikeFileImport) {
52
+ return resolveModuleImport(target, searchPaths, config);
53
+ }
54
+ return findImportCandidate(target, fromFile, getObjectiveCImportIndex(searchPaths), config);
55
+ }
56
+ function resolveAngleImport(inner, searchPaths, config) {
57
+ const normalized = normalizeRepoPath(inner);
58
+ if (normalized.length === 0 || config === undefined)
59
+ return null;
60
+ const slash = normalized.indexOf('/');
61
+ if (slash > 0) {
62
+ const framework = normalized.slice(0, slash);
63
+ const rest = normalized.slice(slash + 1);
64
+ const headersDir = config.frameworks.get(framework);
65
+ if (headersDir !== undefined) {
66
+ const framed = normalizeRepoPath(`${headersDir}/${rest}`);
67
+ if (searchPaths.has(framed))
68
+ return framed;
69
+ }
70
+ }
71
+ for (const searchPath of config.headerSearchPaths) {
72
+ const candidate = normalizeRepoPath(`${searchPath}/${normalized}`);
73
+ if (searchPaths.has(candidate))
74
+ return candidate;
75
+ }
76
+ return null;
77
+ }
78
+ function resolveModuleImport(moduleName, searchPaths, config) {
79
+ if (config === undefined)
80
+ return null;
81
+ const exact = config.modules.get(moduleName);
82
+ if (exact !== undefined && searchPaths.has(exact))
83
+ return exact;
84
+ const root = moduleName.split('.')[0];
85
+ if (root === undefined || root === moduleName)
86
+ return null;
87
+ const fallback = config.modules.get(root);
88
+ return fallback !== undefined && searchPaths.has(fallback) ? fallback : null;
89
+ }
90
+ function findImportCandidate(targetRaw, fromFile, importIndex, config) {
91
+ const normalizedTarget = normalizeRepoPath(targetRaw);
92
+ const fromDir = normalizeRepoPath(path.posix.dirname(normalizeRepoPath(fromFile)));
93
+ const spelledCandidates = new Set([
94
+ normalizeRepoPath(path.posix.join(fromDir, normalizedTarget)),
95
+ normalizedTarget,
96
+ ]);
97
+ if (config !== undefined) {
98
+ for (const searchPath of [...config.userHeaderSearchPaths, ...config.headerSearchPaths]) {
99
+ spelledCandidates.add(normalizeRepoPath(`${searchPath}/${normalizedTarget}`));
100
+ }
101
+ }
102
+ const ext = path.posix.extname(normalizedTarget);
103
+ if (ext.length === 0) {
104
+ for (const base of [...spelledCandidates]) {
105
+ spelledCandidates.add(`${base}.h`);
106
+ spelledCandidates.add(`${base}.m`);
107
+ spelledCandidates.add(`${base}.mm`);
108
+ }
109
+ }
110
+ for (const candidate of spelledCandidates) {
111
+ if (importIndex.filePathSet.has(candidate))
112
+ return candidate;
113
+ }
114
+ let suffixMatch;
115
+ for (const candidate of spelledCandidates) {
116
+ const match = importIndex.suffixMatches.get(candidate);
117
+ if (match !== undefined && (suffixMatch === undefined || match.order < suffixMatch.order)) {
118
+ suffixMatch = match;
119
+ }
120
+ }
121
+ return suffixMatch?.filePath ?? null;
122
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Normalize bare file-scope Objective-C macro markers before parsing.
3
+ *
4
+ * Headers commonly use macro pairs such as `RCT_EXTERN_C_BEGIN` and
5
+ * `RCT_EXTERN_C_END` around C declarations. tree-sitter-objc does not expand
6
+ * those macros; a bare invocation can put the parser into error recovery and
7
+ * hide every Objective-C declaration that follows it. These markers do not
8
+ * contribute syntax on their own, so we replace only the narrow, generic form
9
+ * with spaces before parsing.
10
+ *
11
+ * This is deliberately not macro expansion or a framework-specific allowlist:
12
+ * a candidate must be a whole, all-caps identifier at file scope. Function-like
13
+ * macros, directives, statements, strings, and comments remain untouched.
14
+ * Replacement preserves UTF-16 length and line endings exactly. Candidates are
15
+ * ASCII-only, so their byte offsets are preserved as well.
16
+ */
17
+ /**
18
+ * Elide bare, file-scope macro markers while preserving source positions.
19
+ *
20
+ * `_filePath` is accepted for the LanguageProvider hook signature. The
21
+ * transform is based only on source syntax and deliberately has no framework
22
+ * or repository-specific configuration.
23
+ */
24
+ export declare function preprocessObjectiveCMacroMarkers(source: string, _filePath?: string): string;
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Normalize bare file-scope Objective-C macro markers before parsing.
3
+ *
4
+ * Headers commonly use macro pairs such as `RCT_EXTERN_C_BEGIN` and
5
+ * `RCT_EXTERN_C_END` around C declarations. tree-sitter-objc does not expand
6
+ * those macros; a bare invocation can put the parser into error recovery and
7
+ * hide every Objective-C declaration that follows it. These markers do not
8
+ * contribute syntax on their own, so we replace only the narrow, generic form
9
+ * with spaces before parsing.
10
+ *
11
+ * This is deliberately not macro expansion or a framework-specific allowlist:
12
+ * a candidate must be a whole, all-caps identifier at file scope. Function-like
13
+ * macros, directives, statements, strings, and comments remain untouched.
14
+ * Replacement preserves UTF-16 length and line endings exactly. Candidates are
15
+ * ASCII-only, so their byte offsets are preserved as well.
16
+ */
17
+ function isPreprocessorWhitespace(code) {
18
+ // C preprocessing whitespace includes space, horizontal tab, vertical tab,
19
+ // and form feed. Newlines are split before this scanner sees a line.
20
+ return code === 0x20 || code === 0x09 || code === 0x0b || code === 0x0c;
21
+ }
22
+ function isBareMarkerIdentifier(line) {
23
+ let index = 0;
24
+ while (index < line.length && isPreprocessorWhitespace(line.charCodeAt(index)))
25
+ index++;
26
+ const identifierStart = index;
27
+ const first = line.charCodeAt(index);
28
+ if (!((first >= 0x41 && first <= 0x5a) || first === 0x5f))
29
+ return false;
30
+ let hasUppercaseLetter = false;
31
+ while (index < line.length) {
32
+ const code = line.charCodeAt(index);
33
+ if (code >= 0x41 && code <= 0x5a) {
34
+ hasUppercaseLetter = true;
35
+ index++;
36
+ continue;
37
+ }
38
+ if ((code >= 0x30 && code <= 0x39) || code === 0x5f) {
39
+ index++;
40
+ continue;
41
+ }
42
+ break;
43
+ }
44
+ if (index === identifierStart || !hasUppercaseLetter)
45
+ return false;
46
+ while (index < line.length && isPreprocessorWhitespace(line.charCodeAt(index)))
47
+ index++;
48
+ return index === line.length;
49
+ }
50
+ function isIdentifierContinue(line, index) {
51
+ if (index >= line.length)
52
+ return false;
53
+ const code = line.charCodeAt(index);
54
+ return ((code >= 0x41 && code <= 0x5a) ||
55
+ (code >= 0x61 && code <= 0x7a) ||
56
+ (code >= 0x30 && code <= 0x39) ||
57
+ code === 0x5f);
58
+ }
59
+ function leadingObjCDeclKeyword(line, inBlockComment = false) {
60
+ let index = 0;
61
+ if (inBlockComment) {
62
+ const blockCommentEnd = line.indexOf('*/');
63
+ if (blockCommentEnd < 0)
64
+ return null;
65
+ index = blockCommentEnd + 2;
66
+ }
67
+ while (index < line.length) {
68
+ while (index < line.length && isPreprocessorWhitespace(line.charCodeAt(index)))
69
+ index++;
70
+ if (line.startsWith('//', index))
71
+ return null;
72
+ if (line.startsWith('/*', index)) {
73
+ const blockCommentEnd = line.indexOf('*/', index + 2);
74
+ if (blockCommentEnd < 0)
75
+ return null;
76
+ index = blockCommentEnd + 2;
77
+ continue;
78
+ }
79
+ break;
80
+ }
81
+ if (line.startsWith('@end', index) && !isIdentifierContinue(line, index + 4))
82
+ return 'end';
83
+ for (const keyword of ['@interface', '@protocol', '@implementation']) {
84
+ if (line.startsWith(keyword, index) && !isIdentifierContinue(line, index + keyword.length)) {
85
+ return 'begin';
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ function hasEscapedLineEnding(line) {
91
+ let trailingBackslashes = 0;
92
+ for (let index = line.length - 1; index >= 0 && line.charCodeAt(index) === 0x5c; index--) {
93
+ trailingBackslashes++;
94
+ }
95
+ return trailingBackslashes % 2 === 1;
96
+ }
97
+ function startsPreprocessorDirective(line, state) {
98
+ let index = 0;
99
+ let inBlockComment = state.inBlockComment;
100
+ while (index < line.length) {
101
+ if (inBlockComment) {
102
+ const blockCommentEnd = line.indexOf('*/', index);
103
+ if (blockCommentEnd < 0)
104
+ return false;
105
+ inBlockComment = false;
106
+ index = blockCommentEnd + 2;
107
+ continue;
108
+ }
109
+ while (index < line.length && isPreprocessorWhitespace(line.charCodeAt(index)))
110
+ index++;
111
+ if (line.startsWith('/*', index)) {
112
+ inBlockComment = true;
113
+ index += 2;
114
+ continue;
115
+ }
116
+ if (line.startsWith('//', index))
117
+ return false;
118
+ if (line.charCodeAt(index) !== 0x23)
119
+ return false;
120
+ state.inBlockComment = false;
121
+ return true;
122
+ }
123
+ return false;
124
+ }
125
+ function scanBalancedDelimiters(code, state) {
126
+ if (code === 0x28)
127
+ state.parenDepth++;
128
+ else if (code === 0x29)
129
+ state.parenDepth = Math.max(0, state.parenDepth - 1);
130
+ else if (code === 0x7b)
131
+ state.braceDepth++;
132
+ else if (code === 0x7d)
133
+ state.braceDepth = Math.max(0, state.braceDepth - 1);
134
+ }
135
+ function scanLineBody(line, state, startIndex, trackDelimiters) {
136
+ for (let index = startIndex; index < line.length; index++) {
137
+ const code = line.charCodeAt(index);
138
+ const next = line.charCodeAt(index + 1);
139
+ if (state.inBlockComment) {
140
+ if (code === 0x2a && next === 0x2f) {
141
+ state.inBlockComment = false;
142
+ index++;
143
+ }
144
+ continue;
145
+ }
146
+ if (state.quote !== undefined) {
147
+ if (code === 0x5c) {
148
+ index++;
149
+ }
150
+ else if (line[index] === state.quote) {
151
+ state.quote = undefined;
152
+ }
153
+ continue;
154
+ }
155
+ if (code === 0x2f && next === 0x2f) {
156
+ state.inLineCommentContinuation = hasEscapedLineEnding(line);
157
+ return;
158
+ }
159
+ if (code === 0x2f && next === 0x2a) {
160
+ state.inBlockComment = true;
161
+ index++;
162
+ continue;
163
+ }
164
+ if (code === 0x22 || code === 0x27) {
165
+ state.quote = line[index];
166
+ continue;
167
+ }
168
+ // Directive replacement text is tokens, not C scopes. `{` in
169
+ // `#define WRAP {` must not pin braceDepth for later file-scope markers.
170
+ if (trackDelimiters)
171
+ scanBalancedDelimiters(code, state);
172
+ }
173
+ }
174
+ function scanDirectiveLine(line, state) {
175
+ const continued = hasEscapedLineEnding(line);
176
+ scanLineBody(line, state, 0, false);
177
+ state.inPreprocessorDirective = continued;
178
+ // A quote opened in replacement text does not survive past the directive.
179
+ if (!continued)
180
+ state.quote = undefined;
181
+ }
182
+ function scanLine(line, state) {
183
+ if (state.inLineCommentContinuation) {
184
+ state.inLineCommentContinuation = hasEscapedLineEnding(line);
185
+ // A `// ... \` splice keeps the next physical line in the comment, but the
186
+ // directive ends unless that line is itself backslash-continued.
187
+ if (state.inPreprocessorDirective) {
188
+ state.inPreprocessorDirective = state.inLineCommentContinuation;
189
+ }
190
+ return;
191
+ }
192
+ if (state.inPreprocessorDirective) {
193
+ scanDirectiveLine(line, state);
194
+ return;
195
+ }
196
+ if (startsPreprocessorDirective(line, state)) {
197
+ // Directives can open a block comment (`#define X /*`) that continues
198
+ // onto the next physical line. Scan comment/quote state only.
199
+ scanDirectiveLine(line, state);
200
+ return;
201
+ }
202
+ if (state.inCodeLineContinuation) {
203
+ scanLineBody(line, state, 0, true);
204
+ if (state.quote !== undefined && !hasEscapedLineEnding(line))
205
+ state.quote = undefined;
206
+ state.inCodeLineContinuation =
207
+ !state.inLineCommentContinuation && !state.inBlockComment && hasEscapedLineEnding(line);
208
+ return;
209
+ }
210
+ const keyword = leadingObjCDeclKeyword(line, state.inBlockComment);
211
+ if (keyword === 'begin')
212
+ state.objcDeclDepth++;
213
+ else if (keyword === 'end')
214
+ state.objcDeclDepth = Math.max(0, state.objcDeclDepth - 1);
215
+ scanLineBody(line, state, 0, true);
216
+ if (state.quote !== undefined && !hasEscapedLineEnding(line))
217
+ state.quote = undefined;
218
+ // Line-comment `\` continuation is not a C splice; it must not suppress
219
+ // the next physical line's file-scope marker test.
220
+ state.inCodeLineContinuation =
221
+ !state.inLineCommentContinuation && !state.inBlockComment && hasEscapedLineEnding(line);
222
+ }
223
+ /**
224
+ * Elide bare, file-scope macro markers while preserving source positions.
225
+ *
226
+ * `_filePath` is accepted for the LanguageProvider hook signature. The
227
+ * transform is based only on source syntax and deliberately has no framework
228
+ * or repository-specific configuration.
229
+ */
230
+ export function preprocessObjectiveCMacroMarkers(source, _filePath) {
231
+ const state = {
232
+ inBlockComment: false,
233
+ inLineCommentContinuation: false,
234
+ inCodeLineContinuation: false,
235
+ inPreprocessorDirective: false,
236
+ quote: undefined,
237
+ braceDepth: 0,
238
+ parenDepth: 0,
239
+ objcDeclDepth: 0,
240
+ };
241
+ const segments = source.split(/(\r\n|\n|\r)/);
242
+ let changed = false;
243
+ for (let index = 0; index < segments.length; index += 2) {
244
+ const line = segments[index];
245
+ if (!state.inBlockComment &&
246
+ !state.inLineCommentContinuation &&
247
+ !state.inCodeLineContinuation &&
248
+ !state.inPreprocessorDirective &&
249
+ state.quote === undefined &&
250
+ state.braceDepth === 0 &&
251
+ state.parenDepth === 0 &&
252
+ state.objcDeclDepth === 0 &&
253
+ isBareMarkerIdentifier(line)) {
254
+ segments[index] = ' '.repeat(line.length);
255
+ changed = true;
256
+ continue;
257
+ }
258
+ scanLine(line, state);
259
+ }
260
+ return changed ? segments.join('') : source;
261
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Per-workspace Objective-C import config — the analog of TypeScript's
3
+ * tsconfig, C#'s csproj scan, and C/C++'s header scan.
4
+ *
5
+ * Loaded once per analyze pass via `objectiveCScopeResolver.loadResolutionConfig`
6
+ * and threaded into `resolveObjectiveCImportTarget`. `.h` files are usually
7
+ * classified as C++ unless they contain Objective-C syntax, so the ObjC
8
+ * resolver's `allFilePaths` can miss headers that `#import` / `#include`
9
+ * still name. This scan is what makes those paths visible.
10
+ */
11
+ export interface ObjectiveCResolutionConfig {
12
+ /** Repo-relative `.h` paths discovered on disk (C/C++ header-scan analog). */
13
+ readonly headers: ReadonlySet<string>;
14
+ /**
15
+ * xcconfig `HEADER_SEARCH_PATHS`. Used for both quoted and angle-bracket
16
+ * imports — clang's system/project include path.
17
+ */
18
+ readonly headerSearchPaths: readonly string[];
19
+ /**
20
+ * xcconfig `USER_HEADER_SEARCH_PATHS` plus in-repo `Headers` / `include`
21
+ * roots. Quoted `#import "…"` only. Angle-bracket imports must not use
22
+ * these, or `<Foundation/Foundation.h>` would bind a local decoy.
23
+ */
24
+ readonly userHeaderSearchPaths: readonly string[];
25
+ /** Framework name → repo-relative `*.framework/Headers` directory. */
26
+ readonly frameworks: ReadonlyMap<string, string>;
27
+ /** `@import` module name → umbrella / first header path. */
28
+ readonly modules: ReadonlyMap<string, string>;
29
+ }
30
+ export declare function emptyObjectiveCResolutionConfig(): ObjectiveCResolutionConfig;
31
+ export declare function coerceObjectiveCResolutionConfig(value: unknown): ObjectiveCResolutionConfig | undefined;
32
+ export declare function loadObjectiveCResolutionConfig(repoPath: string): ObjectiveCResolutionConfig;
33
+ export declare function scanObjectiveCWorkspace(repoPath: string): ObjectiveCResolutionConfig;
34
+ export declare function parseXcconfigSearchPaths(source: string): {
35
+ readonly headerSearchPaths: string[];
36
+ readonly userHeaderSearchPaths: string[];
37
+ };
38
+ export declare function parseModuleMap(source: string, mapDir: string): ReadonlyArray<readonly [string, string]>;
39
+ export declare function normalizeRepoPath(value: string): string;
40
+ /** Collapse `.` / `..` in scanned config paths. Import targets stay raw. */
41
+ export declare function collapseRepoPath(value: string): string;