@lzehrung/codegraph 3.0.1 → 3.1.0

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 (630) hide show
  1. package/README.md +17 -17
  2. package/codegraph-skill/codegraph/SKILL.md +3 -0
  3. package/dist/agent/artifact.d.ts.map +1 -1
  4. package/dist/agent/artifact.js +4 -9
  5. package/dist/agent/artifact.js.map +1 -1
  6. package/dist/agent/call-hierarchy.d.ts +4 -2
  7. package/dist/agent/call-hierarchy.d.ts.map +1 -1
  8. package/dist/agent/call-hierarchy.js +20 -29
  9. package/dist/agent/call-hierarchy.js.map +1 -1
  10. package/dist/agent/explain.d.ts.map +1 -1
  11. package/dist/agent/explain.js +12 -11
  12. package/dist/agent/explain.js.map +1 -1
  13. package/dist/agent/explore.d.ts.map +1 -1
  14. package/dist/agent/explore.js +2 -11
  15. package/dist/agent/explore.js.map +1 -1
  16. package/dist/agent/file-view.d.ts.map +1 -1
  17. package/dist/agent/file-view.js +4 -12
  18. package/dist/agent/file-view.js.map +1 -1
  19. package/dist/agent/normalize.d.ts +0 -3
  20. package/dist/agent/normalize.d.ts.map +1 -1
  21. package/dist/agent/normalize.js +1 -7
  22. package/dist/agent/normalize.js.map +1 -1
  23. package/dist/agent/orient.d.ts.map +1 -1
  24. package/dist/agent/orient.js +2 -6
  25. package/dist/agent/orient.js.map +1 -1
  26. package/dist/agent/packet.d.ts.map +1 -1
  27. package/dist/agent/packet.js +2 -5
  28. package/dist/agent/packet.js.map +1 -1
  29. package/dist/agent/query-index/content.d.ts.map +1 -1
  30. package/dist/agent/query-index/content.js +2 -6
  31. package/dist/agent/query-index/content.js.map +1 -1
  32. package/dist/agent/query-index/update.d.ts.map +1 -1
  33. package/dist/agent/query-index/update.js +8 -45
  34. package/dist/agent/query-index/update.js.map +1 -1
  35. package/dist/agent/query-index/worker-pool.d.ts.map +1 -1
  36. package/dist/agent/query-index/worker-pool.js +2 -1
  37. package/dist/agent/query-index/worker-pool.js.map +1 -1
  38. package/dist/agent/refactor-plan.d.ts +2 -2
  39. package/dist/agent/refactor-plan.d.ts.map +1 -1
  40. package/dist/agent/refactor-plan.js +11 -57
  41. package/dist/agent/refactor-plan.js.map +1 -1
  42. package/dist/agent/rename-preview.d.ts.map +1 -1
  43. package/dist/agent/rename-preview.js +166 -23
  44. package/dist/agent/rename-preview.js.map +1 -1
  45. package/dist/agent/search.d.ts.map +1 -1
  46. package/dist/agent/search.js +7 -22
  47. package/dist/agent/search.js.map +1 -1
  48. package/dist/agent/semantic-symbols.d.ts +1 -1
  49. package/dist/agent/semantic-symbols.d.ts.map +1 -1
  50. package/dist/agent/semantic-symbols.js +2 -5
  51. package/dist/agent/semantic-symbols.js.map +1 -1
  52. package/dist/agent/semantic.d.ts +5 -0
  53. package/dist/agent/semantic.d.ts.map +1 -1
  54. package/dist/agent/semantic.js +12 -1
  55. package/dist/agent/semantic.js.map +1 -1
  56. package/dist/agent/session.d.ts +9 -0
  57. package/dist/agent/session.d.ts.map +1 -1
  58. package/dist/agent/session.js +59 -41
  59. package/dist/agent/session.js.map +1 -1
  60. package/dist/agent/type-hierarchy.d.ts +4 -2
  61. package/dist/agent/type-hierarchy.d.ts.map +1 -1
  62. package/dist/agent/type-hierarchy.js +19 -31
  63. package/dist/agent/type-hierarchy.js.map +1 -1
  64. package/dist/agent/workspace-symbols.d.ts +1 -1
  65. package/dist/agent/workspace-symbols.d.ts.map +1 -1
  66. package/dist/agent/workspace-symbols.js +7 -15
  67. package/dist/agent/workspace-symbols.js.map +1 -1
  68. package/dist/analysis-summary.d.ts +1 -4
  69. package/dist/analysis-summary.d.ts.map +1 -1
  70. package/dist/analysis-summary.js +58 -19
  71. package/dist/analysis-summary.js.map +1 -1
  72. package/dist/bin/cli.js +35471 -23021
  73. package/dist/bin/query-index-worker.js +268 -241
  74. package/dist/bootstrap/tree-sitter-languages.d.ts +2 -0
  75. package/dist/bootstrap/tree-sitter-languages.d.ts.map +1 -1
  76. package/dist/bootstrap/tree-sitter-languages.js +6 -19
  77. package/dist/bootstrap/tree-sitter-languages.js.map +1 -1
  78. package/dist/chunking/chunk-matches.d.ts.map +1 -1
  79. package/dist/chunking/chunk-matches.js +6 -42
  80. package/dist/chunking/chunk-matches.js.map +1 -1
  81. package/dist/chunking/chunk-split.d.ts +7 -0
  82. package/dist/chunking/chunk-split.d.ts.map +1 -1
  83. package/dist/chunking/chunk-split.js +3 -3
  84. package/dist/chunking/chunk-split.js.map +1 -1
  85. package/dist/chunking/chunk-text-file.js +2 -30
  86. package/dist/chunking/chunk-text-file.js.map +1 -1
  87. package/dist/cli/affected.d.ts.map +1 -1
  88. package/dist/cli/affected.js +1 -9
  89. package/dist/cli/affected.js.map +1 -1
  90. package/dist/cli/call-hierarchy.js +3 -6
  91. package/dist/cli/call-hierarchy.js.map +1 -1
  92. package/dist/cli/chunk.d.ts.map +1 -1
  93. package/dist/cli/chunk.js +4 -11
  94. package/dist/cli/chunk.js.map +1 -1
  95. package/dist/cli/command-table.d.ts.map +1 -1
  96. package/dist/cli/command-table.js +3 -0
  97. package/dist/cli/command-table.js.map +1 -1
  98. package/dist/cli/context.d.ts +1 -0
  99. package/dist/cli/context.d.ts.map +1 -1
  100. package/dist/cli/context.js +1 -1
  101. package/dist/cli/context.js.map +1 -1
  102. package/dist/cli/doctor.d.ts.map +1 -1
  103. package/dist/cli/doctor.js +1 -11
  104. package/dist/cli/doctor.js.map +1 -1
  105. package/dist/cli/graph.d.ts +4 -12
  106. package/dist/cli/graph.d.ts.map +1 -1
  107. package/dist/cli/graph.js +17 -8
  108. package/dist/cli/graph.js.map +1 -1
  109. package/dist/cli/help.d.ts +3 -3
  110. package/dist/cli/help.d.ts.map +1 -1
  111. package/dist/cli/help.js +6 -4
  112. package/dist/cli/help.js.map +1 -1
  113. package/dist/cli/index.d.ts +2 -12
  114. package/dist/cli/index.d.ts.map +1 -1
  115. package/dist/cli/index.js +2 -5
  116. package/dist/cli/index.js.map +1 -1
  117. package/dist/cli/links.d.ts.map +1 -1
  118. package/dist/cli/links.js +4 -10
  119. package/dist/cli/links.js.map +1 -1
  120. package/dist/cli/mcp.d.ts.map +1 -1
  121. package/dist/cli/mcp.js +1 -0
  122. package/dist/cli/mcp.js.map +1 -1
  123. package/dist/cli/module-locals.d.ts +8 -0
  124. package/dist/cli/module-locals.d.ts.map +1 -0
  125. package/dist/cli/module-locals.js +9 -0
  126. package/dist/cli/module-locals.js.map +1 -0
  127. package/dist/cli/navigation.d.ts +2 -0
  128. package/dist/cli/navigation.d.ts.map +1 -1
  129. package/dist/cli/navigation.js +3 -5
  130. package/dist/cli/navigation.js.map +1 -1
  131. package/dist/cli/options.d.ts.map +1 -1
  132. package/dist/cli/options.js +2 -1
  133. package/dist/cli/options.js.map +1 -1
  134. package/dist/cli/pretty.d.ts +1 -0
  135. package/dist/cli/pretty.d.ts.map +1 -1
  136. package/dist/cli/pretty.js +6 -8
  137. package/dist/cli/pretty.js.map +1 -1
  138. package/dist/cli/refactor-plan.js +2 -5
  139. package/dist/cli/refactor-plan.js.map +1 -1
  140. package/dist/cli/rename-preview.js +2 -5
  141. package/dist/cli/rename-preview.js.map +1 -1
  142. package/dist/cli/review.d.ts +6 -16
  143. package/dist/cli/review.d.ts.map +1 -1
  144. package/dist/cli/review.js +2 -0
  145. package/dist/cli/review.js.map +1 -1
  146. package/dist/cli/server.d.ts.map +1 -1
  147. package/dist/cli/server.js +7 -10
  148. package/dist/cli/server.js.map +1 -1
  149. package/dist/cli/type-hierarchy.js +8 -8
  150. package/dist/cli/type-hierarchy.js.map +1 -1
  151. package/dist/document-links/asciidoc.d.ts.map +1 -1
  152. package/dist/document-links/asciidoc.js +4 -16
  153. package/dist/document-links/asciidoc.js.map +1 -1
  154. package/dist/document-links/check.d.ts.map +1 -1
  155. package/dist/document-links/check.js +1 -3
  156. package/dist/document-links/check.js.map +1 -1
  157. package/dist/document-links/html.d.ts.map +1 -1
  158. package/dist/document-links/html.js +6 -44
  159. package/dist/document-links/html.js.map +1 -1
  160. package/dist/document-links/markdown.d.ts.map +1 -1
  161. package/dist/document-links/markdown.js +4 -13
  162. package/dist/document-links/markdown.js.map +1 -1
  163. package/dist/document-links/rst.d.ts.map +1 -1
  164. package/dist/document-links/rst.js +7 -31
  165. package/dist/document-links/rst.js.map +1 -1
  166. package/dist/document-links/sfc.d.ts.map +1 -1
  167. package/dist/document-links/sfc.js +2 -5
  168. package/dist/document-links/sfc.js.map +1 -1
  169. package/dist/document-links/shared.d.ts +2 -0
  170. package/dist/document-links/shared.d.ts.map +1 -1
  171. package/dist/document-links/shared.js +13 -0
  172. package/dist/document-links/shared.js.map +1 -1
  173. package/dist/drift/artifact.d.ts.map +1 -1
  174. package/dist/drift/artifact.js +4 -27
  175. package/dist/drift/artifact.js.map +1 -1
  176. package/dist/drift/graph-edges.d.ts +4 -0
  177. package/dist/drift/graph-edges.d.ts.map +1 -0
  178. package/dist/drift/graph-edges.js +15 -0
  179. package/dist/drift/graph-edges.js.map +1 -0
  180. package/dist/drift/snapshot.d.ts.map +1 -1
  181. package/dist/drift/snapshot.js +2 -17
  182. package/dist/drift/snapshot.js.map +1 -1
  183. package/dist/duplicates/unit-cache.d.ts +11 -1
  184. package/dist/duplicates/unit-cache.d.ts.map +1 -1
  185. package/dist/duplicates/unit-cache.js +20 -2
  186. package/dist/duplicates/unit-cache.js.map +1 -1
  187. package/dist/duplicates/units.d.ts +2 -1
  188. package/dist/duplicates/units.d.ts.map +1 -1
  189. package/dist/duplicates/units.js +23 -22
  190. package/dist/duplicates/units.js.map +1 -1
  191. package/dist/graph-builder.d.ts +1 -1
  192. package/dist/graph-builder.d.ts.map +1 -1
  193. package/dist/graph-builder.js +3 -2
  194. package/dist/graph-builder.js.map +1 -1
  195. package/dist/graph-edge-collector.d.ts +3 -1
  196. package/dist/graph-edge-collector.d.ts.map +1 -1
  197. package/dist/graph-edge-collector.js +38 -6
  198. package/dist/graph-edge-collector.js.map +1 -1
  199. package/dist/graphs/angularjs.d.ts.map +1 -1
  200. package/dist/graphs/angularjs.js +2 -9
  201. package/dist/graphs/angularjs.js.map +1 -1
  202. package/dist/graphs/edge-resolution.d.ts +4 -0
  203. package/dist/graphs/edge-resolution.d.ts.map +1 -1
  204. package/dist/graphs/edge-resolution.js +2 -0
  205. package/dist/graphs/edge-resolution.js.map +1 -1
  206. package/dist/graphs/external/manifests.d.ts.map +1 -1
  207. package/dist/graphs/external/manifests.js +1 -6
  208. package/dist/graphs/external/manifests.js.map +1 -1
  209. package/dist/graphs/specifiers.d.ts.map +1 -1
  210. package/dist/graphs/specifiers.js +47 -26
  211. package/dist/graphs/specifiers.js.map +1 -1
  212. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +2 -0
  213. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
  214. package/dist/graphs/symbol-graph-detailed/edge-passes.js +9 -3
  215. package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
  216. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +3 -3
  217. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
  218. package/dist/graphs/symbol-graph-detailed/receiver-calls.js +2 -26
  219. package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
  220. package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
  221. package/dist/graphs/symbol-graph-detailed.js +38 -1
  222. package/dist/graphs/symbol-graph-detailed.js.map +1 -1
  223. package/dist/impact/analyzer.d.ts.map +1 -1
  224. package/dist/impact/analyzer.js +23 -17
  225. package/dist/impact/analyzer.js.map +1 -1
  226. package/dist/impact/budgets.d.ts.map +1 -1
  227. package/dist/impact/budgets.js +3 -9
  228. package/dist/impact/budgets.js.map +1 -1
  229. package/dist/impact/call-compatibility.d.ts.map +1 -1
  230. package/dist/impact/call-compatibility.js +3 -12
  231. package/dist/impact/call-compatibility.js.map +1 -1
  232. package/dist/impact/context.d.ts +6 -0
  233. package/dist/impact/context.d.ts.map +1 -1
  234. package/dist/impact/context.js +2 -2
  235. package/dist/impact/context.js.map +1 -1
  236. package/dist/impact/direct.d.ts.map +1 -1
  237. package/dist/impact/direct.js +2 -6
  238. package/dist/impact/direct.js.map +1 -1
  239. package/dist/impact/map.d.ts +3 -1
  240. package/dist/impact/map.d.ts.map +1 -1
  241. package/dist/impact/map.js +12 -5
  242. package/dist/impact/map.js.map +1 -1
  243. package/dist/impact/reference-cache.d.ts.map +1 -1
  244. package/dist/impact/reference-cache.js +1 -24
  245. package/dist/impact/reference-cache.js.map +1 -1
  246. package/dist/impact/report-shared.d.ts +2 -1
  247. package/dist/impact/report-shared.d.ts.map +1 -1
  248. package/dist/impact/report-shared.js +10 -0
  249. package/dist/impact/report-shared.js.map +1 -1
  250. package/dist/impact/report-suggestions.d.ts.map +1 -1
  251. package/dist/impact/report-suggestions.js +2 -8
  252. package/dist/impact/report-suggestions.js.map +1 -1
  253. package/dist/impact/report.d.ts.map +1 -1
  254. package/dist/impact/report.js +2 -8
  255. package/dist/impact/report.js.map +1 -1
  256. package/dist/impact/streaming.d.ts.map +1 -1
  257. package/dist/impact/streaming.js +3 -8
  258. package/dist/impact/streaming.js.map +1 -1
  259. package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
  260. package/dist/indexer/build-cache/manifest.js +10 -108
  261. package/dist/indexer/build-cache/manifest.js.map +1 -1
  262. package/dist/indexer/build-cache/module-cache.d.ts +6 -1
  263. package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
  264. package/dist/indexer/build-cache/module-cache.js +25 -2
  265. package/dist/indexer/build-cache/module-cache.js.map +1 -1
  266. package/dist/indexer/build-cache/options.d.ts +38 -1
  267. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  268. package/dist/indexer/build-cache/options.js +38 -1
  269. package/dist/indexer/build-cache/options.js.map +1 -1
  270. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  271. package/dist/indexer/build-cache/project-snapshot.js +48 -99
  272. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  273. package/dist/indexer/build-cache/reports.d.ts +1 -0
  274. package/dist/indexer/build-cache/reports.d.ts.map +1 -1
  275. package/dist/indexer/build-cache/reports.js +10 -0
  276. package/dist/indexer/build-cache/reports.js.map +1 -1
  277. package/dist/indexer/build-index.d.ts +2 -0
  278. package/dist/indexer/build-index.d.ts.map +1 -1
  279. package/dist/indexer/build-index.js +187 -57
  280. package/dist/indexer/build-index.js.map +1 -1
  281. package/dist/indexer/build-workers.d.ts +7 -1
  282. package/dist/indexer/build-workers.d.ts.map +1 -1
  283. package/dist/indexer/build-workers.js +12 -0
  284. package/dist/indexer/build-workers.js.map +1 -1
  285. package/dist/indexer/call-hierarchy.d.ts.map +1 -1
  286. package/dist/indexer/call-hierarchy.js +5 -17
  287. package/dist/indexer/call-hierarchy.js.map +1 -1
  288. package/dist/indexer/compilation-units.d.ts +32 -20
  289. package/dist/indexer/compilation-units.d.ts.map +1 -1
  290. package/dist/indexer/compilation-units.js +139 -145
  291. package/dist/indexer/compilation-units.js.map +1 -1
  292. package/dist/indexer/cpp-callables.d.ts.map +1 -1
  293. package/dist/indexer/cpp-callables.js +2 -7
  294. package/dist/indexer/cpp-callables.js.map +1 -1
  295. package/dist/indexer/import-types.d.ts +5 -0
  296. package/dist/indexer/import-types.d.ts.map +1 -1
  297. package/dist/indexer/import-types.js.map +1 -1
  298. package/dist/indexer/imports/binding-ranges.d.ts +5 -12
  299. package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
  300. package/dist/indexer/imports/binding-ranges.js +13 -19
  301. package/dist/indexer/imports/binding-ranges.js.map +1 -1
  302. package/dist/indexer/imports/context.d.ts +6 -0
  303. package/dist/indexer/imports/context.d.ts.map +1 -1
  304. package/dist/indexer/imports/import-binding-tables.d.ts +28 -13
  305. package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -1
  306. package/dist/indexer/imports/import-binding-tables.js +179 -178
  307. package/dist/indexer/imports/import-binding-tables.js.map +1 -1
  308. package/dist/indexer/imports/js-text-imports.d.ts +0 -1
  309. package/dist/indexer/imports/js-text-imports.d.ts.map +1 -1
  310. package/dist/indexer/imports/js-text-imports.js +0 -176
  311. package/dist/indexer/imports/js-text-imports.js.map +1 -1
  312. package/dist/indexer/imports/language-specific.d.ts.map +1 -1
  313. package/dist/indexer/imports/language-specific.js +4 -8
  314. package/dist/indexer/imports/language-specific.js.map +1 -1
  315. package/dist/indexer/imports/python.d.ts +0 -1
  316. package/dist/indexer/imports/python.d.ts.map +1 -1
  317. package/dist/indexer/imports/python.js +1 -29
  318. package/dist/indexer/imports/python.js.map +1 -1
  319. package/dist/indexer/imports/text-import-extractors.d.ts +2 -9
  320. package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
  321. package/dist/indexer/imports/text-import-extractors.js +0 -284
  322. package/dist/indexer/imports/text-import-extractors.js.map +1 -1
  323. package/dist/indexer/imports.d.ts +15 -0
  324. package/dist/indexer/imports.d.ts.map +1 -1
  325. package/dist/indexer/imports.js +82 -44
  326. package/dist/indexer/imports.js.map +1 -1
  327. package/dist/indexer/incremental-plan.d.ts +0 -1
  328. package/dist/indexer/incremental-plan.d.ts.map +1 -1
  329. package/dist/indexer/incremental-plan.js +6 -12
  330. package/dist/indexer/incremental-plan.js.map +1 -1
  331. package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -1
  332. package/dist/indexer/name-lookup-policies/implicit-self.js +25 -4
  333. package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -1
  334. package/dist/indexer/name-resolution-types.d.ts +5 -0
  335. package/dist/indexer/name-resolution-types.d.ts.map +1 -1
  336. package/dist/indexer/name-resolution.d.ts.map +1 -1
  337. package/dist/indexer/name-resolution.js +2 -0
  338. package/dist/indexer/name-resolution.js.map +1 -1
  339. package/dist/indexer/navigation-cpp.d.ts.map +1 -1
  340. package/dist/indexer/navigation-cpp.js +3 -5
  341. package/dist/indexer/navigation-cpp.js.map +1 -1
  342. package/dist/indexer/navigation-goto.d.ts +49 -3
  343. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  344. package/dist/indexer/navigation-goto.js +500 -106
  345. package/dist/indexer/navigation-goto.js.map +1 -1
  346. package/dist/indexer/navigation-local.d.ts +7 -0
  347. package/dist/indexer/navigation-local.d.ts.map +1 -1
  348. package/dist/indexer/navigation-local.js +22 -2
  349. package/dist/indexer/navigation-local.js.map +1 -1
  350. package/dist/indexer/navigation-php.d.ts +0 -1
  351. package/dist/indexer/navigation-php.d.ts.map +1 -1
  352. package/dist/indexer/navigation-php.js +1 -7
  353. package/dist/indexer/navigation-php.js.map +1 -1
  354. package/dist/indexer/navigation-references.d.ts +1 -0
  355. package/dist/indexer/navigation-references.d.ts.map +1 -1
  356. package/dist/indexer/navigation-references.js +134 -23
  357. package/dist/indexer/navigation-references.js.map +1 -1
  358. package/dist/indexer/navigation-resolve.d.ts +22 -0
  359. package/dist/indexer/navigation-resolve.d.ts.map +1 -1
  360. package/dist/indexer/navigation-resolve.js +73 -8
  361. package/dist/indexer/navigation-resolve.js.map +1 -1
  362. package/dist/indexer/navigation.d.ts +4 -1
  363. package/dist/indexer/navigation.d.ts.map +1 -1
  364. package/dist/indexer/navigation.js +398 -95
  365. package/dist/indexer/navigation.js.map +1 -1
  366. package/dist/indexer/python-property-decorator.d.ts +11 -0
  367. package/dist/indexer/python-property-decorator.d.ts.map +1 -0
  368. package/dist/indexer/python-property-decorator.js +30 -0
  369. package/dist/indexer/python-property-decorator.js.map +1 -0
  370. package/dist/indexer/shared-owner-identity.d.ts +3 -1
  371. package/dist/indexer/shared-owner-identity.d.ts.map +1 -1
  372. package/dist/indexer/shared-owner-identity.js +40 -12
  373. package/dist/indexer/shared-owner-identity.js.map +1 -1
  374. package/dist/indexer/shared.d.ts +10 -0
  375. package/dist/indexer/shared.d.ts.map +1 -1
  376. package/dist/indexer/shared.js +8 -0
  377. package/dist/indexer/shared.js.map +1 -1
  378. package/dist/indexer/star-import-precedence.d.ts +5 -1
  379. package/dist/indexer/star-import-precedence.d.ts.map +1 -1
  380. package/dist/indexer/star-import-precedence.js +12 -19
  381. package/dist/indexer/star-import-precedence.js.map +1 -1
  382. package/dist/indexer/type-hierarchy.d.ts.map +1 -1
  383. package/dist/indexer/type-hierarchy.js +8 -9
  384. package/dist/indexer/type-hierarchy.js.map +1 -1
  385. package/dist/indexer/types.d.ts +49 -1
  386. package/dist/indexer/types.d.ts.map +1 -1
  387. package/dist/indexer/types.js.map +1 -1
  388. package/dist/indexer/workspace-symbols.d.ts.map +1 -1
  389. package/dist/indexer/workspace-symbols.js +3 -13
  390. package/dist/indexer/workspace-symbols.js.map +1 -1
  391. package/dist/installer/locks.d.ts +1 -0
  392. package/dist/installer/locks.d.ts.map +1 -1
  393. package/dist/installer/locks.js +4 -8
  394. package/dist/installer/locks.js.map +1 -1
  395. package/dist/installer/registry.d.ts.map +1 -1
  396. package/dist/installer/registry.js +9 -15
  397. package/dist/installer/registry.js.map +1 -1
  398. package/dist/languages/callable-arity.d.ts.map +1 -1
  399. package/dist/languages/callable-arity.js +1 -38
  400. package/dist/languages/callable-arity.js.map +1 -1
  401. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  402. package/dist/languages/definitions/csharp.js +5 -13
  403. package/dist/languages/definitions/csharp.js.map +1 -1
  404. package/dist/languages/definitions/java.d.ts.map +1 -1
  405. package/dist/languages/definitions/java.js +4 -13
  406. package/dist/languages/definitions/java.js.map +1 -1
  407. package/dist/languages/definitions/kotlin.d.ts.map +1 -1
  408. package/dist/languages/definitions/kotlin.js +4 -8
  409. package/dist/languages/definitions/kotlin.js.map +1 -1
  410. package/dist/languages/definitions/python.d.ts.map +1 -1
  411. package/dist/languages/definitions/python.js +5 -3
  412. package/dist/languages/definitions/python.js.map +1 -1
  413. package/dist/languages/import-statement-parsers.d.ts +0 -30
  414. package/dist/languages/import-statement-parsers.d.ts.map +1 -1
  415. package/dist/languages/import-statement-parsers.js +1 -81
  416. package/dist/languages/import-statement-parsers.js.map +1 -1
  417. package/dist/languages/sfc.d.ts.map +1 -1
  418. package/dist/languages/sfc.js +8 -43
  419. package/dist/languages/sfc.js.map +1 -1
  420. package/dist/lifecycle/manifest.d.ts.map +1 -1
  421. package/dist/lifecycle/manifest.js +11 -29
  422. package/dist/lifecycle/manifest.js.map +1 -1
  423. package/dist/mcp/handlers.d.ts +21 -0
  424. package/dist/mcp/handlers.d.ts.map +1 -1
  425. package/dist/mcp/handlers.js +66 -20
  426. package/dist/mcp/handlers.js.map +1 -1
  427. package/dist/mcp/http-transport.d.ts.map +1 -1
  428. package/dist/mcp/http-transport.js +5 -1
  429. package/dist/mcp/http-transport.js.map +1 -1
  430. package/dist/mcp/project-watcher.d.ts +125 -0
  431. package/dist/mcp/project-watcher.d.ts.map +1 -0
  432. package/dist/mcp/project-watcher.js +643 -0
  433. package/dist/mcp/project-watcher.js.map +1 -0
  434. package/dist/mcp/server.d.ts.map +1 -1
  435. package/dist/mcp/server.js +5 -1
  436. package/dist/mcp/server.js.map +1 -1
  437. package/dist/native/byte-index.d.ts +1 -0
  438. package/dist/native/byte-index.d.ts.map +1 -1
  439. package/dist/native/byte-index.js +1 -1
  440. package/dist/native/byte-index.js.map +1 -1
  441. package/dist/native/contracts.d.ts +1 -0
  442. package/dist/native/contracts.d.ts.map +1 -1
  443. package/dist/native/native-backend-report.d.ts +2 -1
  444. package/dist/native/native-backend-report.d.ts.map +1 -1
  445. package/dist/native/native-backend-report.js +23 -0
  446. package/dist/native/native-backend-report.js.map +1 -1
  447. package/dist/native/tree-shape.d.ts +5 -7
  448. package/dist/native/tree-shape.d.ts.map +1 -1
  449. package/dist/native/tree-shape.js +11 -10
  450. package/dist/native/tree-shape.js.map +1 -1
  451. package/dist/presentation/bounds.d.ts +2 -0
  452. package/dist/presentation/bounds.d.ts.map +1 -1
  453. package/dist/presentation/bounds.js +8 -0
  454. package/dist/presentation/bounds.js.map +1 -1
  455. package/dist/review/candidates.d.ts.map +1 -1
  456. package/dist/review/candidates.js +4 -25
  457. package/dist/review/candidates.js.map +1 -1
  458. package/dist/review/report.d.ts.map +1 -1
  459. package/dist/review/report.js +4 -2
  460. package/dist/review/report.js.map +1 -1
  461. package/dist/review/summaries.d.ts.map +1 -1
  462. package/dist/review/summaries.js +14 -35
  463. package/dist/review/summaries.js.map +1 -1
  464. package/dist/review.d.ts.map +1 -1
  465. package/dist/review.js +4 -5
  466. package/dist/review.js.map +1 -1
  467. package/dist/scss/navigation.d.ts +13 -0
  468. package/dist/scss/navigation.d.ts.map +1 -0
  469. package/dist/scss/navigation.js +150 -0
  470. package/dist/scss/navigation.js.map +1 -0
  471. package/dist/scss/resolution.d.ts +190 -0
  472. package/dist/scss/resolution.d.ts.map +1 -0
  473. package/dist/scss/resolution.js +1802 -0
  474. package/dist/scss/resolution.js.map +1 -0
  475. package/dist/scss/syntax.d.ts +181 -0
  476. package/dist/scss/syntax.d.ts.map +1 -0
  477. package/dist/scss/syntax.js +1436 -0
  478. package/dist/scss/syntax.js.map +1 -0
  479. package/dist/sql/classify-sql-file.d.ts +7 -0
  480. package/dist/sql/classify-sql-file.d.ts.map +1 -1
  481. package/dist/sql/classify-sql-file.js +9 -0
  482. package/dist/sql/classify-sql-file.js.map +1 -1
  483. package/dist/sql/extract-facts.d.ts.map +1 -1
  484. package/dist/sql/extract-facts.js +517 -77
  485. package/dist/sql/extract-facts.js.map +1 -1
  486. package/dist/sql/lex.d.ts +100 -1
  487. package/dist/sql/lex.d.ts.map +1 -1
  488. package/dist/sql/lex.js +473 -11
  489. package/dist/sql/lex.js.map +1 -1
  490. package/dist/sql/lookup.d.ts +17 -0
  491. package/dist/sql/lookup.d.ts.map +1 -1
  492. package/dist/sql/lookup.js +21 -0
  493. package/dist/sql/lookup.js.map +1 -1
  494. package/dist/sql/navigation.d.ts +28 -1
  495. package/dist/sql/navigation.d.ts.map +1 -1
  496. package/dist/sql/navigation.js +474 -84
  497. package/dist/sql/navigation.js.map +1 -1
  498. package/dist/sql/object-mentions.d.ts +24 -0
  499. package/dist/sql/object-mentions.d.ts.map +1 -0
  500. package/dist/sql/object-mentions.js +233 -0
  501. package/dist/sql/object-mentions.js.map +1 -0
  502. package/dist/sql/review.d.ts +3 -0
  503. package/dist/sql/review.d.ts.map +1 -1
  504. package/dist/sql/review.js +15 -14
  505. package/dist/sql/review.js.map +1 -1
  506. package/dist/sql/routine-mentions.d.ts +61 -0
  507. package/dist/sql/routine-mentions.d.ts.map +1 -0
  508. package/dist/sql/routine-mentions.js +868 -0
  509. package/dist/sql/routine-mentions.js.map +1 -0
  510. package/dist/sql/source-graph.d.ts +18 -3
  511. package/dist/sql/source-graph.d.ts.map +1 -1
  512. package/dist/sql/source-graph.js +109 -32
  513. package/dist/sql/source-graph.js.map +1 -1
  514. package/dist/sqlite/raw-query-worker-pool.d.ts.map +1 -1
  515. package/dist/sqlite/raw-query-worker-pool.js +2 -0
  516. package/dist/sqlite/raw-query-worker-pool.js.map +1 -1
  517. package/dist/sqlite/types.d.ts +6 -5
  518. package/dist/sqlite/types.d.ts.map +1 -1
  519. package/dist/sqlite/write.d.ts.map +1 -1
  520. package/dist/sqlite/write.js.map +1 -1
  521. package/dist/sqlite-driver.d.ts +0 -1
  522. package/dist/sqlite-driver.d.ts.map +1 -1
  523. package/dist/sqlite-driver.js +0 -11
  524. package/dist/sqlite-driver.js.map +1 -1
  525. package/dist/terraform/navigation.d.ts.map +1 -1
  526. package/dist/terraform/navigation.js +1 -3
  527. package/dist/terraform/navigation.js.map +1 -1
  528. package/dist/terraform/syntax.d.ts.map +1 -1
  529. package/dist/terraform/syntax.js +1 -4
  530. package/dist/terraform/syntax.js.map +1 -1
  531. package/dist/util/ast.d.ts +5 -0
  532. package/dist/util/ast.d.ts.map +1 -1
  533. package/dist/util/ast.js +10 -0
  534. package/dist/util/ast.js.map +1 -1
  535. package/dist/util/atomic-file.d.ts +22 -0
  536. package/dist/util/atomic-file.d.ts.map +1 -0
  537. package/dist/util/atomic-file.js +106 -0
  538. package/dist/util/atomic-file.js.map +1 -0
  539. package/dist/util/collections.d.ts +5 -0
  540. package/dist/util/collections.d.ts.map +1 -1
  541. package/dist/util/collections.js +26 -0
  542. package/dist/util/collections.js.map +1 -1
  543. package/dist/util/concurrency.d.ts +1 -0
  544. package/dist/util/concurrency.d.ts.map +1 -1
  545. package/dist/util/concurrency.js +5 -0
  546. package/dist/util/concurrency.js.map +1 -1
  547. package/dist/util/confined-file.d.ts.map +1 -1
  548. package/dist/util/confined-file.js +1 -3
  549. package/dist/util/confined-file.js.map +1 -1
  550. package/dist/util/csharp-tree.d.ts +65 -0
  551. package/dist/util/csharp-tree.d.ts.map +1 -0
  552. package/dist/util/csharp-tree.js +266 -0
  553. package/dist/util/csharp-tree.js.map +1 -0
  554. package/dist/util/errors.d.ts +1 -0
  555. package/dist/util/errors.d.ts.map +1 -1
  556. package/dist/util/errors.js +3 -0
  557. package/dist/util/errors.js.map +1 -1
  558. package/dist/util/graph-edges.d.ts +2 -0
  559. package/dist/util/graph-edges.d.ts.map +1 -1
  560. package/dist/util/graph-edges.js +11 -0
  561. package/dist/util/graph-edges.js.map +1 -1
  562. package/dist/util/guards.d.ts +1 -0
  563. package/dist/util/guards.d.ts.map +1 -1
  564. package/dist/util/guards.js +6 -0
  565. package/dist/util/guards.js.map +1 -1
  566. package/dist/util/identifiers.d.ts +0 -24
  567. package/dist/util/identifiers.d.ts.map +1 -1
  568. package/dist/util/identifiers.js +0 -24
  569. package/dist/util/identifiers.js.map +1 -1
  570. package/dist/util/jvm-tree.d.ts +58 -0
  571. package/dist/util/jvm-tree.d.ts.map +1 -0
  572. package/dist/util/jvm-tree.js +153 -0
  573. package/dist/util/jvm-tree.js.map +1 -0
  574. package/dist/util/package-exports.d.ts +0 -22
  575. package/dist/util/package-exports.d.ts.map +1 -1
  576. package/dist/util/package-exports.js +25 -5
  577. package/dist/util/package-exports.js.map +1 -1
  578. package/dist/util/paths.d.ts +1 -0
  579. package/dist/util/paths.d.ts.map +1 -1
  580. package/dist/util/paths.js +10 -4
  581. package/dist/util/paths.js.map +1 -1
  582. package/dist/util/resolution/csharp.d.ts +20 -8
  583. package/dist/util/resolution/csharp.d.ts.map +1 -1
  584. package/dist/util/resolution/csharp.js +126 -127
  585. package/dist/util/resolution/csharp.js.map +1 -1
  586. package/dist/util/resolution/files.d.ts +6 -0
  587. package/dist/util/resolution/files.d.ts.map +1 -1
  588. package/dist/util/resolution/files.js +74 -21
  589. package/dist/util/resolution/files.js.map +1 -1
  590. package/dist/util/resolution/jvm.d.ts +21 -1
  591. package/dist/util/resolution/jvm.d.ts.map +1 -1
  592. package/dist/util/resolution/jvm.js +168 -100
  593. package/dist/util/resolution/jvm.js.map +1 -1
  594. package/dist/util/resolution/project-symbols.d.ts +1 -1
  595. package/dist/util/resolution/project-symbols.d.ts.map +1 -1
  596. package/dist/util/resolution/project-symbols.js.map +1 -1
  597. package/dist/util/resolution/specifier-targets.d.ts +4 -0
  598. package/dist/util/resolution/specifier-targets.d.ts.map +1 -1
  599. package/dist/util/resolution/specifier-targets.js +11 -3
  600. package/dist/util/resolution/specifier-targets.js.map +1 -1
  601. package/dist/util/resolution.d.ts.map +1 -1
  602. package/dist/util/resolution.js +21 -7
  603. package/dist/util/resolution.js.map +1 -1
  604. package/dist/util/syntax-tree.d.ts +16 -0
  605. package/dist/util/syntax-tree.d.ts.map +1 -0
  606. package/dist/util/syntax-tree.js +34 -0
  607. package/dist/util/syntax-tree.js.map +1 -0
  608. package/dist/util/text-scanning.d.ts +6 -0
  609. package/dist/util/text-scanning.d.ts.map +1 -0
  610. package/dist/util/text-scanning.js +35 -0
  611. package/dist/util/text-scanning.js.map +1 -0
  612. package/dist/util/trivia-tables.d.ts +13 -8
  613. package/dist/util/trivia-tables.d.ts.map +1 -1
  614. package/dist/util/trivia-tables.js +13 -72
  615. package/dist/util/trivia-tables.js.map +1 -1
  616. package/dist/util/trivia.d.ts +10 -3
  617. package/dist/util/trivia.d.ts.map +1 -1
  618. package/dist/util/trivia.js +209 -79
  619. package/dist/util/trivia.js.map +1 -1
  620. package/dist/util/windows-process-drain.d.ts.map +1 -1
  621. package/dist/util/windows-process-drain.js.map +1 -1
  622. package/dist/util/worker-threads.d.ts +16 -0
  623. package/dist/util/worker-threads.d.ts.map +1 -1
  624. package/dist/util/worker-threads.js +118 -0
  625. package/dist/util/worker-threads.js.map +1 -1
  626. package/dist/worker/native-worker-pool.d.ts.map +1 -1
  627. package/dist/worker/native-worker-pool.js +2 -1
  628. package/dist/worker/native-worker-pool.js.map +1 -1
  629. package/docs/mcp.md +27 -2
  630. package/package.json +7 -7
@@ -0,0 +1,1436 @@
1
+ import { collectLineStartOffsets, positionAtOffset } from "../util/lines.js";
2
+ import { buildTriviaMask, skipScssEscape } from "../util/trivia.js";
3
+ /**
4
+ * SCSS module facts read from source text.
5
+ *
6
+ * The pinned grammar leaves `@use as`, `@forward as`/`show`/`hide`, namespaced access, and
7
+ * `@extend %placeholder` as ERROR nodes or opaque values, so those forms are scanned lexically.
8
+ * Comments, strings, and unquoted `url(...)` content stay masked; `#{...}` interpolation stays
9
+ * visible because it is code. The scan is one linear pass. Nothing here decides which file a URL
10
+ * loads.
11
+ */
12
+ export const SCSS_LANGUAGE_ID = "scss";
13
+ /** A Sass identifier. Hyphens are significant spelling; a leading `$` marks a variable. */
14
+ export const SCSS_IDENTIFIER_PATTERN = /^\$?-?[A-Za-z_\u0080-\uFFFF][A-Za-z0-9_\u0080-\uFFFF-]*$/u;
15
+ const DYNAMIC_FORMS = new Set([
16
+ "load-css",
17
+ "get-function",
18
+ "get-mixin",
19
+ "module-variables",
20
+ "module-functions",
21
+ "module-mixins",
22
+ "variable-exists",
23
+ "global-variable-exists",
24
+ "function-exists",
25
+ "mixin-exists",
26
+ "call",
27
+ ]);
28
+ /**
29
+ * Global built-ins that name a member by a string. A bare call is one of these unless a user
30
+ * function of that name is already declared. `get-mixin` and the `module-*` lookups are not global.
31
+ */
32
+ const LEGACY_BARE_FORMS = new Set([
33
+ "get-function",
34
+ "variable-exists",
35
+ "global-variable-exists",
36
+ "function-exists",
37
+ "mixin-exists",
38
+ "call",
39
+ ]);
40
+ /** Sass compares identifiers after treating `_` as `-`, and ignores one leading `$` or `%`. */
41
+ export function sassCanonical(name) {
42
+ const bare = name.startsWith("$") || name.startsWith("%") ? name.slice(1) : name;
43
+ return bare.replace(/_/g, "-");
44
+ }
45
+ /** The name without its `$` or `%` sigil. */
46
+ export function sassBare(name) {
47
+ return name.startsWith("$") || name.startsWith("%") ? name.slice(1) : name;
48
+ }
49
+ /**
50
+ * The namespace `@use url` binds without `as`: the last path segment without a leading `_` and
51
+ * without anything from the first `.`. Sass compares namespaces exactly, so the spelling is kept.
52
+ * Null when the segment is empty.
53
+ */
54
+ function sassDefaultNamespace(url) {
55
+ const clean = (url.split(/[?#]/u)[0] ?? url).replace(/\/+$/u, "");
56
+ let segment = clean.split("/").pop() ?? clean;
57
+ if (segment.includes(":"))
58
+ segment = segment.split(":").pop() ?? segment;
59
+ if (segment.startsWith("_"))
60
+ segment = segment.slice(1);
61
+ const dot = segment.indexOf(".");
62
+ if (dot >= 0)
63
+ segment = segment.slice(0, dot);
64
+ return segment || null;
65
+ }
66
+ /** Stem used to compare a module URL or a directory with a stylesheet file name. */
67
+ export function moduleStem(pathOrUrl) {
68
+ const clean = (pathOrUrl.split(/[?#]/u)[0] ?? pathOrUrl).replace(/[\\/]+$/u, "");
69
+ let segment = clean.split(/[\\/]/u).pop() ?? clean;
70
+ segment = segment.replace(/\.(scss|sass|css)$/iu, "");
71
+ if (segment.includes(":"))
72
+ segment = segment.split(":").pop() ?? segment;
73
+ segment = segment.replace(/^[~_]+/u, "");
74
+ return sassCanonical(segment);
75
+ }
76
+ export function isSassBuiltinUrl(url) {
77
+ return url.trim().startsWith("sass:");
78
+ }
79
+ /** Range of `[start, end)` in the file the facts came from. */
80
+ export function scssOffsetRange(facts, start, end) {
81
+ return { start: positionAtOffset(facts.lineStarts, start), end: positionAtOffset(facts.lineStarts, end) };
82
+ }
83
+ /** Offset of a 1-based `line` and `column`, or -1 when the line does not exist. */
84
+ export function scssOffsetAt(facts, line, column) {
85
+ const lineStart = facts.lineStarts[line - 1];
86
+ return lineStart === undefined ? -1 : lineStart + Math.max(0, column - 1);
87
+ }
88
+ function isSpaceUnit(unit) {
89
+ return unit === 0x20 || unit === 0x09 || unit === 0x0a || unit === 0x0d || unit === 0x0c;
90
+ }
91
+ function isIdentStart(unit) {
92
+ return (unit >= 0x41 && unit <= 0x5a) || (unit >= 0x61 && unit <= 0x7a) || unit === 0x5f || unit >= 0x80;
93
+ }
94
+ function isIdentPart(unit) {
95
+ return isIdentStart(unit) || (unit >= 0x30 && unit <= 0x39) || unit === 0x2d;
96
+ }
97
+ function readIdent(source, index) {
98
+ let cursor = index;
99
+ while (source.charCodeAt(cursor) === 0x2d)
100
+ cursor += 1;
101
+ if (!isIdentStart(source.charCodeAt(cursor)))
102
+ return null;
103
+ cursor += 1;
104
+ while (isIdentPart(source.charCodeAt(cursor)))
105
+ cursor += 1;
106
+ return { text: source.slice(index, cursor), end: cursor };
107
+ }
108
+ function readQuoted(source, index) {
109
+ const quote = source[index];
110
+ if (quote !== '"' && quote !== "'")
111
+ return null;
112
+ let text = "";
113
+ let cursor = index + 1;
114
+ while (cursor < source.length) {
115
+ const ch = source[cursor];
116
+ if (ch === "\\") {
117
+ text += source[cursor + 1] ?? "";
118
+ cursor += 2;
119
+ continue;
120
+ }
121
+ if (ch === quote)
122
+ return { text, end: cursor + 1 };
123
+ text += ch ?? "";
124
+ cursor += 1;
125
+ }
126
+ return { text, end: source.length };
127
+ }
128
+ function isDynamicForm(name) {
129
+ return DYNAMIC_FORMS.has(name);
130
+ }
131
+ /**
132
+ * The dynamic lookup that a function or mixin name spells, or null. Sass reads `_` as `-` in such
133
+ * a name, so `get_function` and `get-function` are one function.
134
+ */
135
+ export function dynamicFormOf(name) {
136
+ const folded = name.replace(/_/g, "-");
137
+ return isDynamicForm(folded) ? folded : null;
138
+ }
139
+ /**
140
+ * Sass reads an `@import` as plain CSS, not as a module load, when the URL ends in `.css`, starts
141
+ * with `//`, `http://`, or `https://`, holds an interpolation, or is written as `url(...)`, or when
142
+ * the argument has media queries.
143
+ */
144
+ function isPlainCssImportUrl(url) {
145
+ if (url.endsWith(".css") || url.includes("#{"))
146
+ return true;
147
+ return url.startsWith("//") || url.startsWith("http://") || url.startsWith("https://");
148
+ }
149
+ /** Blocks of these at-rules share the variable scope that holds them. */
150
+ const FLOW_RULES = new Set(["if", "else", "each", "for", "while"]);
151
+ export function extractScssFacts(source) {
152
+ const mask = buildTriviaMask(source, SCSS_LANGUAGE_ID, { holes: true, maskCssUrls: true });
153
+ const lineStarts = collectLineStartOffsets(source);
154
+ const length = source.length;
155
+ const consumed = new Uint8Array(length);
156
+ const declarations = [];
157
+ const loads = [];
158
+ const uses = [];
159
+ const locals = [];
160
+ const callableLocals = [];
161
+ const flowAssignments = [];
162
+ const dynamics = [];
163
+ const interpolatedPlaceholderRanges = [];
164
+ let interpolatedExtend = false;
165
+ let interpolatedPlaceholder = false;
166
+ const parens = [];
167
+ const braces = [];
168
+ const blocks = [];
169
+ const metaNamespaces = new Set();
170
+ let metaStar = false;
171
+ let pendingLocals = [];
172
+ let statementStart = true;
173
+ let inInclude = false;
174
+ let statementRule = "";
175
+ let nonFlowBlocks = 0;
176
+ const globalVariables = new Set();
177
+ /**
178
+ * How many genuine bindings of each name are in scope: parameters, loop variables, and block
179
+ * variables. A provisional import-flow assignment is not counted, so the next assignment in
180
+ * that flow is not hidden by it.
181
+ */
182
+ const localCounts = new Map();
183
+ /** Flow-assignment bindings that must not change {@link localCounts}. */
184
+ const provisionalFlows = new Set();
185
+ /**
186
+ * Canonical names of the top-level functions and mixins declared so far. A later bare call or
187
+ * include of that name is the user callable, not a `sass:meta` lookup. A scoped callable lives
188
+ * on its block instead, and a declaration later in the file does not own an earlier use.
189
+ */
190
+ const declaredFunctions = new Set();
191
+ const declaredMixins = new Set();
192
+ let paramsParenAt = -1;
193
+ let callParenAt = -1;
194
+ /** Offset of `(` after `selector` in an `@supports` head, so the paren is selector context. */
195
+ let selectorParenAt = -1;
196
+ /** Offset where the current statement starts: after the last `;` or block brace. */
197
+ let statementBegin = 0;
198
+ let headCache = null;
199
+ /** Set by {@link opensStyleRule}. The outer scan cannot see the closure write on `headCache`. */
200
+ let selectorHeadInterpolated = false;
201
+ /** True from `@mixin` / `@function` until the body brace opens, so parameter defaults are deferred. */
202
+ let pendingCallable = false;
203
+ /** Nested mixin and function bodies. Calls inside them run when the callable is invoked. */
204
+ let callableDepth = 0;
205
+ /** A loud-comment interpolation is code, but not part of its surrounding statement. */
206
+ let commentMask;
207
+ let commentState = null;
208
+ const rangeOf = (start, end) => ({
209
+ start: positionAtOffset(lineStarts, start),
210
+ end: positionAtOffset(lineStarts, end),
211
+ });
212
+ const consume = (start, end) => {
213
+ for (let cursor = start; cursor < end; cursor += 1)
214
+ consumed[cursor] = 1;
215
+ };
216
+ const touch = () => {
217
+ const top = parens[parens.length - 1];
218
+ if (top)
219
+ top.argStart = false;
220
+ };
221
+ /** Skips whitespace and masked text. */
222
+ const skipBlank = (from) => {
223
+ let cursor = from;
224
+ while (cursor < length && (mask[cursor] || isSpaceUnit(source.charCodeAt(cursor))))
225
+ cursor += 1;
226
+ return cursor;
227
+ };
228
+ /** Skips whitespace and comments, and stops at a quote, so a module URL can be read from the source. */
229
+ const skipSpaceAndComments = (from) => {
230
+ let cursor = from;
231
+ while (cursor < length) {
232
+ const unit = source.charCodeAt(cursor);
233
+ if (isSpaceUnit(unit)) {
234
+ cursor += 1;
235
+ continue;
236
+ }
237
+ if (unit === 0x2f && source.charCodeAt(cursor + 1) === 0x2f) {
238
+ while (cursor < length && source[cursor] !== "\n" && source[cursor] !== "\r")
239
+ cursor += 1;
240
+ continue;
241
+ }
242
+ if (unit === 0x2f && source.charCodeAt(cursor + 1) === 0x2a) {
243
+ const close = source.indexOf("*/", cursor + 2);
244
+ cursor = close < 0 ? length : close + 2;
245
+ continue;
246
+ }
247
+ break;
248
+ }
249
+ return cursor;
250
+ };
251
+ const makeLocal = (nameStart, nameEnd, from) => ({
252
+ canonical: sassCanonical(source.slice(nameStart + 1, nameEnd)),
253
+ spelling: source.slice(nameStart, nameEnd),
254
+ from,
255
+ to: -1,
256
+ range: rangeOf(nameStart, nameEnd),
257
+ });
258
+ const addUse = (use) => {
259
+ // Sass folds `_` into `-` for variables, mixins, and functions, but compares a placeholder as written.
260
+ const canonical = use.kind === "placeholder" ? use.text : sassCanonical(use.text);
261
+ const recorded = { ...use, canonical, hitStart: use.hitStart ?? use.nameStart };
262
+ if ((use.syntax === "call" || use.syntax === "include") && (callableDepth > 0 || pendingCallable)) {
263
+ recorded.deferred = true;
264
+ }
265
+ if (use.syntax === "call" || use.syntax === "include") {
266
+ const form = dynamicFormOf(use.text);
267
+ if (form)
268
+ recorded.dynamic = { form, arg: readCallArgument(use.nameEnd), at: use.nameStart };
269
+ }
270
+ uses.push(recorded);
271
+ };
272
+ const addVariableUse = (start, end, namespace) => {
273
+ addUse({
274
+ kind: "variable",
275
+ syntax: "variable",
276
+ namespace,
277
+ text: source.slice(start, end),
278
+ nameStart: start,
279
+ nameEnd: end,
280
+ loadIndex: null,
281
+ });
282
+ };
283
+ const readNameAt = (from) => {
284
+ const cursor = skipBlank(from);
285
+ const ident = readIdent(source, cursor);
286
+ return ident ? { text: ident.text, start: cursor, end: ident.end } : null;
287
+ };
288
+ /** Reads `name`, `ns.name`, or `ns.$name` starting at `from`. */
289
+ const readMemberAt = (from) => {
290
+ const first = readNameAt(from);
291
+ if (!first)
292
+ return null;
293
+ const dot = skipBlank(first.end);
294
+ if (source.charCodeAt(dot) !== 0x2e) {
295
+ return {
296
+ namespace: null,
297
+ member: first.text,
298
+ memberText: first.text,
299
+ start: first.start,
300
+ memberStart: first.start,
301
+ memberEnd: first.end,
302
+ end: first.end,
303
+ };
304
+ }
305
+ if (source.charCodeAt(dot + 1) === 0x24) {
306
+ const variable = readIdent(source, dot + 2);
307
+ if (!variable)
308
+ return null;
309
+ return {
310
+ namespace: first.text,
311
+ member: variable.text,
312
+ memberText: source.slice(dot + 1, variable.end),
313
+ start: first.start,
314
+ memberStart: dot + 1,
315
+ memberEnd: variable.end,
316
+ end: variable.end,
317
+ };
318
+ }
319
+ const member = readIdent(source, dot + 1);
320
+ if (!member)
321
+ return null;
322
+ return {
323
+ namespace: first.text,
324
+ member: member.text,
325
+ memberText: member.text,
326
+ start: first.start,
327
+ memberStart: dot + 1,
328
+ memberEnd: member.end,
329
+ end: member.end,
330
+ };
331
+ };
332
+ /** The first argument of a call when it is a string literal, read from the source. */
333
+ const readCallArgument = (from) => {
334
+ const paren = skipBlank(from);
335
+ if (source.charCodeAt(paren) !== 0x28)
336
+ return null;
337
+ return readQuoted(source, skipSpaceAndComments(paren + 1))?.text ?? null;
338
+ };
339
+ /**
340
+ * The lookup that a call through `sass:meta` names, or null. The name folds `_` into `-`, and the
341
+ * namespace compares as written, so `meta.get_function` is a lookup and `my-meta.get-function` is
342
+ * not when the module is bound to `my_meta`. This pass does not load files, so a namespace whose
343
+ * module `@forward`s `sass:meta` (directly or through another forward) is classified later, when
344
+ * resolution can see that load.
345
+ */
346
+ const metaCallForm = (namespace, member) => {
347
+ const form = dynamicFormOf(member);
348
+ if (!form)
349
+ return null;
350
+ const viaMeta = namespace === null ? metaStar : metaNamespaces.has(namespace);
351
+ return viaMeta ? form : null;
352
+ };
353
+ /**
354
+ * True when a mixin or function of this name is already in scope: a top-level declaration seen
355
+ * earlier, or a scoped callable in an open block. `-` and `_` are the same character.
356
+ */
357
+ const callableAlreadyDeclared = (kind, name, at) => {
358
+ const canonical = sassCanonical(name);
359
+ if (kind === "function" ? declaredFunctions.has(canonical) : declaredMixins.has(canonical))
360
+ return true;
361
+ for (let frameIndex = blocks.length - 1; frameIndex >= 0; frameIndex -= 1) {
362
+ const frame = blocks[frameIndex];
363
+ if (!frame)
364
+ continue;
365
+ for (let callableIndex = frame.callables.length - 1; callableIndex >= 0; callableIndex -= 1) {
366
+ const local = frame.callables[callableIndex];
367
+ if (local && local.kind === kind && local.canonical === canonical && at >= local.from)
368
+ return true;
369
+ }
370
+ }
371
+ return false;
372
+ };
373
+ const bindLocal = (frame, local, provisional = false) => {
374
+ frame.locals.push(local);
375
+ locals.push(local);
376
+ if (provisional) {
377
+ provisionalFlows.add(local);
378
+ return;
379
+ }
380
+ localCounts.set(local.canonical, (localCounts.get(local.canonical) ?? 0) + 1);
381
+ };
382
+ const unbindLocal = (local) => {
383
+ if (provisionalFlows.delete(local))
384
+ return;
385
+ const count = (localCounts.get(local.canonical) ?? 1) - 1;
386
+ if (count > 0)
387
+ localCounts.set(local.canonical, count);
388
+ else
389
+ localCounts.delete(local.canonical);
390
+ };
391
+ const openBlock = (braceIndex) => {
392
+ const flow = FLOW_RULES.has(statementRule);
393
+ const callable = pendingCallable;
394
+ if (callable) {
395
+ callableDepth += 1;
396
+ pendingCallable = false;
397
+ }
398
+ const frame = { locals: [], callables: [], flow, callable };
399
+ if (!flow)
400
+ nonFlowBlocks += 1;
401
+ for (const local of pendingLocals) {
402
+ if (local.from < 0)
403
+ local.from = braceIndex;
404
+ bindLocal(frame, local);
405
+ }
406
+ pendingLocals = [];
407
+ braces.push(true);
408
+ blocks.push(frame);
409
+ statementStart = true;
410
+ statementBegin = braceIndex + 1;
411
+ statementRule = "";
412
+ inInclude = false;
413
+ parens.length = 0;
414
+ };
415
+ const closeBlock = (braceIndex) => {
416
+ const frame = blocks.pop();
417
+ if (frame) {
418
+ for (const local of frame.locals) {
419
+ local.to = braceIndex;
420
+ unbindLocal(local);
421
+ }
422
+ for (const callable of frame.callables)
423
+ callable.to = braceIndex;
424
+ if (!frame.flow)
425
+ nonFlowBlocks -= 1;
426
+ if (frame.callable)
427
+ callableDepth -= 1;
428
+ }
429
+ statementStart = true;
430
+ statementBegin = braceIndex + 1;
431
+ statementRule = "";
432
+ inInclude = false;
433
+ parens.length = 0;
434
+ };
435
+ /** Flags and end of the statement whose value starts at `from`: `!default`, `!global`, and its `;`. */
436
+ const statementFlags = (from) => {
437
+ let cursor = from;
438
+ let paren = 0;
439
+ let interpolation = 0;
440
+ let isDefault = false;
441
+ let isGlobal = false;
442
+ while (cursor < length) {
443
+ if (!mask[cursor]) {
444
+ const unit = source.charCodeAt(cursor);
445
+ if (unit === 0x28)
446
+ paren += 1;
447
+ else if (unit === 0x29)
448
+ paren = Math.max(0, paren - 1);
449
+ else if (unit === 0x7b) {
450
+ if (source.charCodeAt(cursor - 1) === 0x23)
451
+ interpolation += 1;
452
+ else if (paren === 0)
453
+ break;
454
+ }
455
+ else if (unit === 0x7d) {
456
+ if (interpolation > 0)
457
+ interpolation -= 1;
458
+ else if (paren === 0)
459
+ break;
460
+ }
461
+ else if (unit === 0x3b && paren === 0 && interpolation === 0)
462
+ break;
463
+ else if (unit === 0x21 && paren === 0) {
464
+ const flag = readIdent(source, cursor + 1);
465
+ if (flag?.text === "default")
466
+ isDefault = true;
467
+ if (flag?.text === "global")
468
+ isGlobal = true;
469
+ cursor = flag ? flag.end : cursor + 1;
470
+ continue;
471
+ }
472
+ }
473
+ cursor += 1;
474
+ }
475
+ return { isDefault, isGlobal, end: cursor };
476
+ };
477
+ const handleCallable = (keyword, from) => {
478
+ const name = readNameAt(from);
479
+ if (!name)
480
+ return from;
481
+ consume(name.start, name.end);
482
+ const enclosing = blocks[blocks.length - 1];
483
+ if (enclosing) {
484
+ const local = { kind: keyword, canonical: sassCanonical(name.text), from: name.end, to: -1 };
485
+ enclosing.callables.push(local);
486
+ callableLocals.push(local);
487
+ }
488
+ else {
489
+ declarations.push({
490
+ kind: keyword,
491
+ name: name.text,
492
+ canonical: sassCanonical(name.text),
493
+ range: rangeOf(name.start, name.end),
494
+ topLevel: true,
495
+ isDefault: false,
496
+ });
497
+ if (keyword === "function")
498
+ declaredFunctions.add(sassCanonical(name.text));
499
+ else
500
+ declaredMixins.add(sassCanonical(name.text));
501
+ }
502
+ const paren = skipBlank(name.end);
503
+ if (source.charCodeAt(paren) === 0x28)
504
+ paramsParenAt = paren;
505
+ pendingCallable = true;
506
+ return name.end;
507
+ };
508
+ const handleInclude = (from) => {
509
+ const member = readMemberAt(from);
510
+ if (!member)
511
+ return from;
512
+ consume(member.start, member.end);
513
+ const after = skipBlank(member.end);
514
+ if (source.charCodeAt(after) === 0x28)
515
+ callParenAt = after;
516
+ inInclude = true;
517
+ const dynamicForm = metaCallForm(member.namespace, member.member);
518
+ // A user mixin already declared owns a bare include, including `load-css` after `@use "sass:meta" as *`.
519
+ // A namespaced `meta.load-css` stays a lookup, and a mixin declared later does not own this include.
520
+ const ownedByMixin = dynamicForm !== null &&
521
+ member.namespace === null &&
522
+ callableAlreadyDeclared("mixin", member.member, member.memberStart);
523
+ if (dynamicForm && !ownedByMixin) {
524
+ dynamics.push({ form: dynamicForm, arg: readCallArgument(member.end), at: member.memberStart });
525
+ return member.end;
526
+ }
527
+ addUse({
528
+ kind: "mixin",
529
+ syntax: "include",
530
+ namespace: member.namespace,
531
+ text: member.memberText,
532
+ nameStart: member.memberStart,
533
+ nameEnd: member.memberEnd,
534
+ loadIndex: null,
535
+ });
536
+ return member.end;
537
+ };
538
+ /** `@extend` lists any number of selectors; each `%placeholder` among them is a use. */
539
+ const handleExtend = (from) => {
540
+ let cursor = from;
541
+ let interpolation = 0;
542
+ let interpolatedSelector = false;
543
+ while (cursor < length) {
544
+ if (mask[cursor]) {
545
+ cursor += 1;
546
+ continue;
547
+ }
548
+ const unit = source.charCodeAt(cursor);
549
+ if (unit === 0x2c && !interpolation)
550
+ interpolatedSelector = false;
551
+ if (unit === 0x23 && source.charCodeAt(cursor + 1) === 0x7b) {
552
+ interpolatedExtend = true;
553
+ interpolatedSelector = true;
554
+ }
555
+ if (unit === 0x3b)
556
+ break;
557
+ if (unit === 0x7b) {
558
+ if (source.charCodeAt(cursor - 1) !== 0x23)
559
+ break;
560
+ interpolation += 1;
561
+ }
562
+ if (unit === 0x7d) {
563
+ if (!interpolation)
564
+ break;
565
+ interpolation -= 1;
566
+ }
567
+ if (unit === 0x25 && !interpolation) {
568
+ const ident = readIdent(source, cursor + 1);
569
+ if (ident) {
570
+ const afterName = skipSpaceAndComments(ident.end);
571
+ const interpolatedSuffix = source.charCodeAt(afterName) === 0x23 && source.charCodeAt(afterName + 1) === 0x7b;
572
+ if (interpolatedSelector || interpolatedSuffix) {
573
+ interpolatedPlaceholderRanges.push(rangeOf(cursor, ident.end));
574
+ }
575
+ else {
576
+ addUse({
577
+ kind: "placeholder",
578
+ syntax: "extend",
579
+ namespace: null,
580
+ text: ident.text,
581
+ nameStart: cursor + 1,
582
+ nameEnd: ident.end,
583
+ hitStart: cursor,
584
+ loadIndex: null,
585
+ });
586
+ }
587
+ consume(cursor, ident.end);
588
+ cursor = ident.end;
589
+ continue;
590
+ }
591
+ }
592
+ cursor += 1;
593
+ }
594
+ return from;
595
+ };
596
+ /** `@each $a, $b in list {` and `@for $i from 1 through 3 {`: the variables belong to the block. */
597
+ const handleLoopVariables = (from, several) => {
598
+ let cursor = skipBlank(from);
599
+ while (source.charCodeAt(cursor) === 0x24) {
600
+ const variable = readIdent(source, cursor + 1);
601
+ if (!variable)
602
+ break;
603
+ pendingLocals.push(makeLocal(cursor, variable.end, -1));
604
+ consume(cursor, variable.end);
605
+ cursor = skipBlank(variable.end);
606
+ if (!several || source.charCodeAt(cursor) !== 0x2c)
607
+ break;
608
+ cursor = skipBlank(cursor + 1);
609
+ }
610
+ return from;
611
+ };
612
+ const collectWithKeys = (load, parenIndex) => {
613
+ let cursor = parenIndex + 1;
614
+ let depth = 1;
615
+ while (cursor < length && depth > 0) {
616
+ if (mask[cursor]) {
617
+ cursor += 1;
618
+ continue;
619
+ }
620
+ const unit = source.charCodeAt(cursor);
621
+ if (unit === 0x28)
622
+ depth += 1;
623
+ if (unit === 0x29)
624
+ depth -= 1;
625
+ if (depth === 1 && unit === 0x24) {
626
+ const name = readIdent(source, cursor + 1);
627
+ if (name) {
628
+ const colon = skipBlank(name.end);
629
+ if (source.charCodeAt(colon) === 0x3a) {
630
+ load.withKeys.push({
631
+ name: source.slice(cursor, name.end),
632
+ range: rangeOf(cursor, name.end),
633
+ kind: "variable",
634
+ });
635
+ consume(cursor, name.end);
636
+ }
637
+ cursor = name.end;
638
+ continue;
639
+ }
640
+ }
641
+ cursor += 1;
642
+ }
643
+ };
644
+ const readNameList = (from) => {
645
+ const names = [];
646
+ let cursor = from;
647
+ while (cursor < length) {
648
+ cursor = skipSpaceAndComments(cursor);
649
+ const unit = source.charCodeAt(cursor);
650
+ if (unit === 0x3b || unit === 0x7b || cursor >= length)
651
+ break;
652
+ const word = readIdent(source, cursor);
653
+ if (unit === 0x24) {
654
+ const variable = readIdent(source, cursor + 1);
655
+ if (!variable)
656
+ break;
657
+ names.push({
658
+ name: source.slice(cursor, variable.end),
659
+ range: rangeOf(cursor, variable.end),
660
+ kind: "variable",
661
+ });
662
+ consume(cursor, variable.end);
663
+ cursor = skipSpaceAndComments(variable.end);
664
+ }
665
+ else if (word) {
666
+ names.push({ name: word.text, range: rangeOf(cursor, word.end), kind: "callable" });
667
+ consume(cursor, word.end);
668
+ cursor = skipSpaceAndComments(word.end);
669
+ }
670
+ else {
671
+ break;
672
+ }
673
+ if (source.charCodeAt(cursor) !== 0x2c)
674
+ break;
675
+ cursor += 1;
676
+ }
677
+ return { names, end: cursor };
678
+ };
679
+ const recordLoad = (load) => {
680
+ const loadIndex = loads.length;
681
+ loads.push(load);
682
+ if (load.kind === "use" && load.url.trim() === "sass:meta") {
683
+ if (load.star)
684
+ metaStar = true;
685
+ if (load.namespace !== null)
686
+ metaNamespaces.add(load.namespace);
687
+ }
688
+ for (const key of load.withKeys) {
689
+ addUse({
690
+ kind: "variable",
691
+ syntax: "config",
692
+ namespace: null,
693
+ text: key.name,
694
+ nameStart: key.range.start.index ?? 0,
695
+ nameEnd: key.range.end.index ?? 0,
696
+ loadIndex,
697
+ });
698
+ }
699
+ const lists = [
700
+ [load.show ?? [], "show"],
701
+ [load.hide ?? [], "hide"],
702
+ ];
703
+ for (const [names, syntax] of lists) {
704
+ for (const name of names) {
705
+ addUse({
706
+ kind: name.kind,
707
+ syntax,
708
+ namespace: null,
709
+ text: name.name,
710
+ nameStart: name.range.start.index ?? 0,
711
+ nameEnd: name.range.end.index ?? 0,
712
+ loadIndex,
713
+ });
714
+ }
715
+ }
716
+ };
717
+ const handleModuleLoad = (keyword, from) => {
718
+ const urlAt = skipSpaceAndComments(from);
719
+ const url = readQuoted(source, urlAt);
720
+ if (!url)
721
+ return from;
722
+ const load = {
723
+ kind: keyword,
724
+ url: url.text,
725
+ namespace: keyword === "use" ? sassDefaultNamespace(url.text) : null,
726
+ star: false,
727
+ prefix: "",
728
+ show: null,
729
+ hide: null,
730
+ withKeys: [],
731
+ nested: false,
732
+ at: from,
733
+ };
734
+ let cursor = url.end;
735
+ let stopAt = cursor;
736
+ while (cursor < length) {
737
+ cursor = skipSpaceAndComments(cursor);
738
+ const unit = source.charCodeAt(cursor);
739
+ if (unit === 0x3b || unit === 0x7b || cursor >= length) {
740
+ stopAt = cursor;
741
+ break;
742
+ }
743
+ const word = readIdent(source, cursor);
744
+ if (!word) {
745
+ stopAt = cursor;
746
+ break;
747
+ }
748
+ if (word.text === "as") {
749
+ const aliasAt = skipSpaceAndComments(word.end);
750
+ if (source.charCodeAt(aliasAt) === 0x2a) {
751
+ load.star = true;
752
+ load.namespace = null;
753
+ cursor = aliasAt + 1;
754
+ continue;
755
+ }
756
+ const alias = readIdent(source, aliasAt);
757
+ if (!alias) {
758
+ stopAt = word.end;
759
+ break;
760
+ }
761
+ const afterAlias = skipSpaceAndComments(alias.end);
762
+ if (source.charCodeAt(afterAlias) === 0x2a) {
763
+ load.prefix = alias.text;
764
+ if (keyword === "forward")
765
+ load.namespace = null;
766
+ cursor = afterAlias + 1;
767
+ continue;
768
+ }
769
+ if (keyword === "use") {
770
+ load.namespace = alias.text;
771
+ load.star = false;
772
+ }
773
+ cursor = alias.end;
774
+ continue;
775
+ }
776
+ if (word.text === "with") {
777
+ const paren = skipSpaceAndComments(word.end);
778
+ if (source.charCodeAt(paren) === 0x28)
779
+ collectWithKeys(load, paren);
780
+ stopAt = paren;
781
+ break;
782
+ }
783
+ if (word.text === "show" || word.text === "hide") {
784
+ const list = readNameList(word.end);
785
+ if (word.text === "show")
786
+ load.show = list.names;
787
+ else
788
+ load.hide = list.names;
789
+ cursor = list.end;
790
+ continue;
791
+ }
792
+ stopAt = cursor;
793
+ break;
794
+ }
795
+ recordLoad(load);
796
+ return Math.max(from + 1, stopAt);
797
+ };
798
+ /** The end of an `@import` argument written as `url(...)`, or -1 when `cursor` does not start one. */
799
+ const urlFunctionEnd = (cursor) => {
800
+ if (source.slice(cursor, cursor + 4).toLowerCase() !== "url(")
801
+ return -1;
802
+ const inner = skipSpaceAndComments(cursor + 4);
803
+ const quoted = readQuoted(source, inner);
804
+ const close = source.indexOf(")", quoted ? quoted.end : inner);
805
+ return close < 0 ? length : close + 1;
806
+ };
807
+ /**
808
+ * Records the Sass loads of an `@import`. The arguments stay in the main scan, so a variable in a
809
+ * media query or in the interpolation of `url(...)` is a use. A quoted URL is the exception: Sass
810
+ * keeps it as raw text, so `@import "https://x/#{$a}.css"` reads nothing.
811
+ */
812
+ const handleImport = (from) => {
813
+ let cursor = from;
814
+ while (cursor < length) {
815
+ cursor = skipSpaceAndComments(cursor);
816
+ const quoted = readQuoted(source, cursor);
817
+ if (quoted)
818
+ consume(cursor, quoted.end);
819
+ const functionEnd = quoted ? -1 : urlFunctionEnd(cursor);
820
+ if (!quoted && functionEnd < 0)
821
+ break;
822
+ const end = quoted ? quoted.end : functionEnd;
823
+ const after = skipSpaceAndComments(end);
824
+ const next = source.charCodeAt(after);
825
+ const hasModifiers = after < length && next !== 0x2c && next !== 0x3b && next !== 0x7d;
826
+ const isPlain = functionEnd >= 0 || hasModifiers || isPlainCssImportUrl(quoted?.text ?? "");
827
+ if (quoted && !isPlain) {
828
+ loads.push({
829
+ kind: "import",
830
+ url: quoted.text,
831
+ namespace: null,
832
+ star: false,
833
+ prefix: "",
834
+ show: null,
835
+ hide: null,
836
+ withKeys: [],
837
+ nested: blocks.length > 0,
838
+ at: cursor,
839
+ });
840
+ }
841
+ cursor = after;
842
+ if (hasModifiers) {
843
+ while (cursor < length && source.charCodeAt(cursor) !== 0x3b && source.charCodeAt(cursor) !== 0x7b) {
844
+ if (source.charCodeAt(cursor) === 0x2c) {
845
+ const argument = skipSpaceAndComments(cursor + 1);
846
+ if (readQuoted(source, argument) || urlFunctionEnd(argument) >= 0)
847
+ break;
848
+ }
849
+ cursor += 1;
850
+ }
851
+ }
852
+ if (source.charCodeAt(cursor) !== 0x2c)
853
+ break;
854
+ cursor += 1;
855
+ }
856
+ return from;
857
+ };
858
+ /** The offset after the `}` that closes the interpolation whose `{` is at `open`, or -1 when it never closes. */
859
+ const interpolationEnd = (open) => {
860
+ let depth = 0;
861
+ for (let cursor = open; cursor < length; cursor += 1) {
862
+ if (mask[cursor])
863
+ continue;
864
+ const unit = source.charCodeAt(cursor);
865
+ if (unit === 0x7b)
866
+ depth += 1;
867
+ if (unit === 0x7d) {
868
+ depth -= 1;
869
+ if (!depth)
870
+ return cursor + 1;
871
+ }
872
+ }
873
+ return -1;
874
+ };
875
+ /**
876
+ * The offset of the `:` after a custom property name that starts at `start` (`--name`, or a name
877
+ * with an interpolation such as `--#{$prefix}name`), or -1 when the text is no custom property.
878
+ */
879
+ const customPropertyColon = (start) => {
880
+ if (source.charCodeAt(start) !== 0x2d || source.charCodeAt(start + 1) !== 0x2d)
881
+ return -1;
882
+ let cursor = start + 2;
883
+ while (cursor < length && !mask[cursor]) {
884
+ const unit = source.charCodeAt(cursor);
885
+ if (unit === 0x23 && source.charCodeAt(cursor + 1) === 0x7b) {
886
+ const end = interpolationEnd(cursor + 1);
887
+ if (end < 0)
888
+ return -1;
889
+ cursor = end;
890
+ }
891
+ else if (isIdentPart(unit)) {
892
+ cursor += 1;
893
+ }
894
+ else {
895
+ break;
896
+ }
897
+ }
898
+ const colon = skipBlank(cursor);
899
+ return source.charCodeAt(colon) === 0x3a ? colon : -1;
900
+ };
901
+ /**
902
+ * The value of a custom property (`--name: value`) is literal CSS, and only `#{...}` is code. The
903
+ * text from `from` to the end of the declaration is consumed, so a `$name` or a call in it is no
904
+ * use, and a brace in it opens no block. An escape is one token before any of those checks,
905
+ * including a hex escape of up to six digits and its optional whitespace, so `\}` does not close
906
+ * the block. The declaration ends at a `;` or at the `}` of its block, outside any bracket.
907
+ */
908
+ const skipCustomPropertyValue = (from) => {
909
+ let depth = 0;
910
+ let cursor = from;
911
+ while (cursor < length) {
912
+ if (mask[cursor]) {
913
+ cursor += 1;
914
+ continue;
915
+ }
916
+ const unit = source.charCodeAt(cursor);
917
+ if (unit === 0x5c) {
918
+ const end = skipScssEscape(source, cursor);
919
+ while (cursor < end) {
920
+ consumed[cursor] = 1;
921
+ cursor += 1;
922
+ }
923
+ continue;
924
+ }
925
+ if (unit === 0x23 && source.charCodeAt(cursor + 1) === 0x7b) {
926
+ const end = interpolationEnd(cursor + 1);
927
+ if (end < 0)
928
+ return;
929
+ cursor = end;
930
+ continue;
931
+ }
932
+ if (!depth && (unit === 0x7d || unit === 0x3b))
933
+ return;
934
+ if (unit === 0x28 || unit === 0x5b || unit === 0x7b)
935
+ depth += 1;
936
+ if (unit === 0x29 || unit === 0x5d || unit === 0x7d)
937
+ depth = Math.max(0, depth - 1);
938
+ consumed[cursor] = 1;
939
+ cursor += 1;
940
+ }
941
+ };
942
+ const handleAtRule = (keyword, from) => {
943
+ if (keyword === "mixin" || keyword === "function")
944
+ return handleCallable(keyword, from);
945
+ if (keyword === "include")
946
+ return handleInclude(from);
947
+ if (keyword === "extend")
948
+ return handleExtend(from);
949
+ if (keyword === "use" || keyword === "forward")
950
+ return handleModuleLoad(keyword, from);
951
+ if (keyword === "import")
952
+ return handleImport(from);
953
+ if (keyword === "each")
954
+ return handleLoopVariables(from, true);
955
+ if (keyword === "for")
956
+ return handleLoopVariables(from, false);
957
+ return from;
958
+ };
959
+ /**
960
+ * The offset of the `,` or `)` that ends a parameter whose default value starts at `from`. A
961
+ * comma or a parenthesis inside a nested bracket or an interpolation does not end it.
962
+ */
963
+ const parameterEnd = (from) => {
964
+ let depth = 0;
965
+ let interpolation = 0;
966
+ for (let cursor = from; cursor < length; cursor += 1) {
967
+ if (mask[cursor])
968
+ continue;
969
+ const unit = source.charCodeAt(cursor);
970
+ if (unit === 0x23 && source.charCodeAt(cursor + 1) === 0x7b) {
971
+ interpolation += 1;
972
+ cursor += 1;
973
+ }
974
+ else if (interpolation) {
975
+ if (unit === 0x7b)
976
+ interpolation += 1;
977
+ if (unit === 0x7d)
978
+ interpolation -= 1;
979
+ }
980
+ else if (unit === 0x28 || unit === 0x5b) {
981
+ depth += 1;
982
+ }
983
+ else if (unit === 0x29 || unit === 0x5d) {
984
+ if (!depth)
985
+ return cursor;
986
+ depth -= 1;
987
+ }
988
+ else if (unit === 0x2c && !depth) {
989
+ return cursor;
990
+ }
991
+ else if (unit === 0x3b || unit === 0x7b || unit === 0x7d) {
992
+ return cursor;
993
+ }
994
+ }
995
+ return length;
996
+ };
997
+ /** One `$name` token: a parameter, a declaration, a keyword-argument name, or a use. */
998
+ const handleVariable = (start) => {
999
+ const variable = readIdent(source, start + 1);
1000
+ if (!variable)
1001
+ return start + 1;
1002
+ const end = variable.end;
1003
+ const next = skipBlank(end);
1004
+ const isColon = source.charCodeAt(next) === 0x3a && source.charCodeAt(next + 1) !== 0x3a;
1005
+ const top = parens[parens.length - 1];
1006
+ if (top?.mode === "params" && top.argStart) {
1007
+ // A parameter hides a member from the end of its default value to the end of the body. Its own
1008
+ // default still reads the member. The default of a later parameter reads the parameter.
1009
+ pendingLocals.push(makeLocal(start, end, isColon ? parameterEnd(next + 1) : end));
1010
+ }
1011
+ else if (statementStart && isColon) {
1012
+ const flags = statementFlags(next);
1013
+ const canonical = sassCanonical(variable.text);
1014
+ // A flow-control block that holds no rule or mixin shares the scope of the file: assigning
1015
+ // a name the file already declared changes that variable instead of hiding it. A loop
1016
+ // variable of the same name is the exception: `@each $x in ...` binds `$x` for the block, so
1017
+ // `$x: $x + 1` changes the loop variable and leaves the file variable alone. A provisional
1018
+ // import-flow binding is not such a local, so `$x: 2; $x: 3` records both assignments.
1019
+ const boundLocally = localCounts.has(canonical);
1020
+ const fileFlow = blocks.length > 0 && nonFlowBlocks === 0 && !boundLocally;
1021
+ const reassigns = fileFlow && globalVariables.has(canonical);
1022
+ if (!blocks.length || flags.isGlobal || reassigns) {
1023
+ globalVariables.add(canonical);
1024
+ declarations.push({
1025
+ kind: "variable",
1026
+ name: source.slice(start, end),
1027
+ canonical,
1028
+ range: rangeOf(start, end),
1029
+ topLevel: true,
1030
+ isDefault: flags.isDefault,
1031
+ });
1032
+ }
1033
+ else if (fileFlow && loads.some((load) => load.kind === "import" && !load.nested)) {
1034
+ // A file-scope flow block shares the file scope. An earlier @import may already have
1035
+ // declared this name; resolution joins every such assignment or keeps the local.
1036
+ // `@use ... as *` is not an import. Sass creates a local in the flow block, and that
1037
+ // local does not assign or escape to the star-loaded variable.
1038
+ const frame = blocks[blocks.length - 1];
1039
+ const local = makeLocal(start, end, flags.end);
1040
+ flowAssignments.push({ canonical, range: local.range, local });
1041
+ if (frame)
1042
+ bindLocal(frame, local, true);
1043
+ }
1044
+ else {
1045
+ // The new variable hides a member only after its own statement, so `$x: $x + 1` reads the member.
1046
+ const frame = blocks[blocks.length - 1];
1047
+ if (frame)
1048
+ bindLocal(frame, makeLocal(start, end, flags.end));
1049
+ }
1050
+ }
1051
+ else if (!(top?.mode === "call" && top.argStart && isColon)) {
1052
+ addVariableUse(start, end, null);
1053
+ }
1054
+ return end;
1055
+ };
1056
+ /**
1057
+ * True inside the head of a style rule: a block follows the head, and the statement is no
1058
+ * at-rule, except `@at-root`, which takes a selector. There `:is(` and `:not(` are selectors, not
1059
+ * calls, and a `%name` declares a placeholder. A declaration ends at a `;` or at the `}` of its
1060
+ * own block. The scan runs once per statement.
1061
+ */
1062
+ const opensStyleRule = () => {
1063
+ if (headCache?.begin === statementBegin) {
1064
+ selectorHeadInterpolated = headCache.interpolated;
1065
+ return headCache.styleRule;
1066
+ }
1067
+ let cursor = skipBlank(statementBegin);
1068
+ const isAtRule = source.charCodeAt(cursor) === 0x40;
1069
+ const takesSelector = !isAtRule || readIdent(source, cursor + 1)?.text === "at-root";
1070
+ let interpolation = 0;
1071
+ let block = false;
1072
+ let interpolatedHead = false;
1073
+ for (; cursor < length; cursor += 1) {
1074
+ if (mask[cursor])
1075
+ continue;
1076
+ const unit = source.charCodeAt(cursor);
1077
+ if (unit === 0x23 && source.charCodeAt(cursor + 1) === 0x7b) {
1078
+ interpolatedHead = true;
1079
+ interpolation += 1;
1080
+ cursor += 1;
1081
+ continue;
1082
+ }
1083
+ if (interpolation) {
1084
+ if (unit === 0x7b)
1085
+ interpolation += 1;
1086
+ if (unit === 0x7d)
1087
+ interpolation -= 1;
1088
+ continue;
1089
+ }
1090
+ if (unit === 0x7b) {
1091
+ block = true;
1092
+ break;
1093
+ }
1094
+ if (unit === 0x7d || unit === 0x3b)
1095
+ break;
1096
+ }
1097
+ selectorHeadInterpolated = interpolatedHead;
1098
+ headCache = { begin: statementBegin, styleRule: block && takesSelector, interpolated: interpolatedHead };
1099
+ return headCache.styleRule;
1100
+ };
1101
+ /**
1102
+ * True when `:` starts a CSS pseudo, not a Sass call: a style-rule head, or `selector(...)` in
1103
+ * an `@supports` head. Interpolation inside either is an expression, so `#{has(1)}` stays a call.
1104
+ */
1105
+ const inSelectorContext = () => {
1106
+ if (braces.includes(false))
1107
+ return false;
1108
+ if (parens.some((frame) => frame.mode === "selector"))
1109
+ return true;
1110
+ return opensStyleRule();
1111
+ };
1112
+ /** `ns.member` access, a call, or a plain identifier. Returns the offset to continue from. */
1113
+ const handleIdentifier = (start, ident) => {
1114
+ if (inInclude && ident.text === "using") {
1115
+ const paren = skipBlank(ident.end);
1116
+ if (source.charCodeAt(paren) === 0x28)
1117
+ paramsParenAt = paren;
1118
+ return ident.end;
1119
+ }
1120
+ const previous = source.charCodeAt(start - 1);
1121
+ if (previous === 0x2e || previous === 0x23)
1122
+ return ident.end;
1123
+ const next = skipBlank(ident.end);
1124
+ if (source.charCodeAt(next) === 0x2e) {
1125
+ const member = readMemberAt(start);
1126
+ if (!member || member.namespace === null)
1127
+ return ident.end;
1128
+ const isVariable = member.memberText.startsWith("$");
1129
+ const isCall = source.charCodeAt(skipBlank(member.end)) === 0x28;
1130
+ const dynamicForm = isCall && !isVariable ? metaCallForm(member.namespace, member.member) : null;
1131
+ if (dynamicForm) {
1132
+ dynamics.push({
1133
+ form: dynamicForm,
1134
+ arg: readCallArgument(member.end),
1135
+ at: member.memberStart,
1136
+ });
1137
+ }
1138
+ else if (isVariable) {
1139
+ addUse({
1140
+ kind: "variable",
1141
+ syntax: "variable",
1142
+ namespace: member.namespace,
1143
+ text: member.memberText,
1144
+ nameStart: member.memberStart,
1145
+ nameEnd: member.memberEnd,
1146
+ loadIndex: null,
1147
+ });
1148
+ }
1149
+ else if (isCall) {
1150
+ addUse({
1151
+ kind: "function",
1152
+ syntax: "call",
1153
+ namespace: member.namespace,
1154
+ text: member.memberText,
1155
+ nameStart: member.memberStart,
1156
+ nameEnd: member.memberEnd,
1157
+ loadIndex: null,
1158
+ });
1159
+ }
1160
+ // Any other `ns.name` text is a selector, a unit, or a file name, not a module member.
1161
+ return member.end;
1162
+ }
1163
+ // `@supports selector(...)` takes a selector. The name is CSS, not a Sass function, and so is
1164
+ // `:has(` inside it. A call in an at-rule expression, such as `@if has(1)`, stays a call.
1165
+ if (statementRule === "supports" && !braces.includes(false) && ident.text.toLowerCase() === "selector") {
1166
+ const paren = skipBlank(ident.end);
1167
+ if (source.charCodeAt(paren) === 0x28) {
1168
+ selectorParenAt = paren;
1169
+ return ident.end;
1170
+ }
1171
+ }
1172
+ if (source.charCodeAt(ident.end) === 0x28) {
1173
+ const folded = dynamicFormOf(ident.text);
1174
+ const legacyForm = folded !== null && LEGACY_BARE_FORMS.has(folded) ? folded : null;
1175
+ // A same-kind function already declared owns the call, at the top level or in a block, even
1176
+ // after `@use "sass:meta" as *` and for names that are not legacy built-ins. A declaration
1177
+ // later in the file does not, so the earlier call stays the built-in.
1178
+ const declaredHere = folded !== null && callableAlreadyDeclared("function", ident.text, start);
1179
+ const bareForm = declaredHere ? null : metaCallForm(null, ident.text);
1180
+ if (bareForm) {
1181
+ dynamics.push({
1182
+ form: bareForm,
1183
+ arg: readCallArgument(ident.end),
1184
+ at: start,
1185
+ });
1186
+ return ident.end;
1187
+ }
1188
+ if (legacyForm && !declaredHere) {
1189
+ dynamics.push({ form: legacyForm, arg: readCallArgument(ident.end), legacyBare: true, at: start });
1190
+ addUse({
1191
+ kind: "function",
1192
+ syntax: "call",
1193
+ namespace: null,
1194
+ text: ident.text,
1195
+ nameStart: start,
1196
+ nameEnd: ident.end,
1197
+ loadIndex: null,
1198
+ });
1199
+ return ident.end;
1200
+ }
1201
+ // A CSS functional pseudo-class or pseudo-element in a selector (`:is(`, `:not(`, `::part(`)
1202
+ // is no Sass function call. `selector(...)` in an `@supports` head is selector context too.
1203
+ if (previous === 0x3a && inSelectorContext())
1204
+ return ident.end;
1205
+ addUse({
1206
+ kind: "function",
1207
+ syntax: "call",
1208
+ namespace: null,
1209
+ text: ident.text,
1210
+ nameStart: start,
1211
+ nameEnd: ident.end,
1212
+ loadIndex: null,
1213
+ });
1214
+ }
1215
+ return ident.end;
1216
+ };
1217
+ let index = 0;
1218
+ while (index < length) {
1219
+ if (commentState && commentMask && !commentMask[index]) {
1220
+ statementStart = commentState.statementStart;
1221
+ statementBegin = commentState.statementBegin;
1222
+ statementRule = commentState.statementRule;
1223
+ inInclude = commentState.inInclude;
1224
+ headCache = commentState.headCache;
1225
+ parens.length = 0;
1226
+ parens.push(...commentState.parens);
1227
+ commentState = null;
1228
+ }
1229
+ if (mask[index] || consumed[index]) {
1230
+ // The trivia mask exposes the expression of a loud comment but masks its `#{` and `}`.
1231
+ // Save the enclosing declaration and argument state before scanning that expression.
1232
+ if (!commentState && mask[index] && source.charCodeAt(index) === 0x23 && source.charCodeAt(index + 1) === 0x7b) {
1233
+ commentMask ??= buildTriviaMask(source, SCSS_LANGUAGE_ID, { maskStrings: false });
1234
+ if (commentMask[index]) {
1235
+ commentState = {
1236
+ statementStart,
1237
+ statementBegin,
1238
+ statementRule,
1239
+ inInclude,
1240
+ parens: parens.slice(),
1241
+ headCache,
1242
+ };
1243
+ statementStart = false;
1244
+ statementRule = "";
1245
+ inInclude = false;
1246
+ parens.length = 0;
1247
+ }
1248
+ }
1249
+ index += 1;
1250
+ continue;
1251
+ }
1252
+ const unit = source.charCodeAt(index);
1253
+ if (isSpaceUnit(unit)) {
1254
+ index += 1;
1255
+ continue;
1256
+ }
1257
+ if (unit === 0x5c) {
1258
+ touch();
1259
+ statementStart = false;
1260
+ index = skipScssEscape(source, index);
1261
+ continue;
1262
+ }
1263
+ if (unit === 0x7b) {
1264
+ if (source.charCodeAt(index - 1) === 0x23) {
1265
+ braces.push(false);
1266
+ statementStart = false;
1267
+ touch();
1268
+ }
1269
+ else {
1270
+ openBlock(index);
1271
+ }
1272
+ index += 1;
1273
+ continue;
1274
+ }
1275
+ if (unit === 0x7d) {
1276
+ const isBlock = braces.pop();
1277
+ if (isBlock === false) {
1278
+ statementStart = false;
1279
+ touch();
1280
+ }
1281
+ else {
1282
+ closeBlock(index);
1283
+ }
1284
+ index += 1;
1285
+ continue;
1286
+ }
1287
+ if (unit === 0x3b) {
1288
+ statementStart = true;
1289
+ statementBegin = index + 1;
1290
+ inInclude = false;
1291
+ statementRule = "";
1292
+ pendingLocals = [];
1293
+ pendingCallable = false;
1294
+ parens.length = 0;
1295
+ index += 1;
1296
+ continue;
1297
+ }
1298
+ if (unit === 0x5b) {
1299
+ touch();
1300
+ parens.push({ mode: "group", argStart: true, bracket: true });
1301
+ statementStart = false;
1302
+ index += 1;
1303
+ continue;
1304
+ }
1305
+ if (unit === 0x5d) {
1306
+ if (parens[parens.length - 1]?.bracket)
1307
+ parens.pop();
1308
+ touch();
1309
+ statementStart = false;
1310
+ index += 1;
1311
+ continue;
1312
+ }
1313
+ if (unit === 0x28) {
1314
+ let mode = "group";
1315
+ if (paramsParenAt === index)
1316
+ mode = "params";
1317
+ else if (selectorParenAt === index)
1318
+ mode = "selector";
1319
+ else if (callParenAt === index || isIdentPart(source.charCodeAt(index - 1)))
1320
+ mode = "call";
1321
+ touch();
1322
+ parens.push({ mode, argStart: true });
1323
+ statementStart = false;
1324
+ index += 1;
1325
+ continue;
1326
+ }
1327
+ if (unit === 0x29) {
1328
+ parens.pop();
1329
+ touch();
1330
+ statementStart = false;
1331
+ index += 1;
1332
+ continue;
1333
+ }
1334
+ if (unit === 0x2c) {
1335
+ const top = parens[parens.length - 1];
1336
+ if (top)
1337
+ top.argStart = true;
1338
+ statementStart = false;
1339
+ index += 1;
1340
+ continue;
1341
+ }
1342
+ if (unit === 0x40) {
1343
+ const keyword = readIdent(source, index + 1);
1344
+ touch();
1345
+ statementStart = false;
1346
+ statementRule = keyword?.text ?? "";
1347
+ index = keyword ? Math.max(handleAtRule(keyword.text, keyword.end), keyword.end) : index + 1;
1348
+ continue;
1349
+ }
1350
+ if (unit === 0x24) {
1351
+ index = handleVariable(index);
1352
+ touch();
1353
+ statementStart = false;
1354
+ continue;
1355
+ }
1356
+ if (unit === 0x25) {
1357
+ const placeholder = readIdent(source, index + 1);
1358
+ // A placeholder in the head of a style rule is a declaration at any depth: Sass extends it
1359
+ // wherever its rule sits, in a media query, in another rule, or in a mixin.
1360
+ if (placeholder && opensStyleRule()) {
1361
+ // `%btn#{$suffix}` and `#{$prefix}%btn` are not the static placeholder `btn`. The name
1362
+ // depends on the interpolation, so it stays out of the static group.
1363
+ if (selectorHeadInterpolated) {
1364
+ interpolatedPlaceholder = true;
1365
+ interpolatedPlaceholderRanges.push(rangeOf(index, placeholder.end));
1366
+ }
1367
+ else {
1368
+ declarations.push({
1369
+ kind: "placeholder",
1370
+ name: placeholder.text,
1371
+ canonical: placeholder.text,
1372
+ range: rangeOf(index + 1, placeholder.end),
1373
+ topLevel: true,
1374
+ isDefault: false,
1375
+ });
1376
+ }
1377
+ }
1378
+ touch();
1379
+ statementStart = false;
1380
+ index = placeholder ? placeholder.end : index + 1;
1381
+ continue;
1382
+ }
1383
+ if (unit === 0x2d || isIdentStart(unit)) {
1384
+ const ident = readIdent(source, index);
1385
+ const startsDeclaration = statementStart;
1386
+ touch();
1387
+ statementStart = false;
1388
+ if (startsDeclaration && unit === 0x2d) {
1389
+ const colon = customPropertyColon(index);
1390
+ if (colon >= 0)
1391
+ skipCustomPropertyValue(colon + 1);
1392
+ }
1393
+ index = ident ? Math.max(handleIdentifier(index, ident), ident.end) : index + 1;
1394
+ continue;
1395
+ }
1396
+ touch();
1397
+ statementStart = false;
1398
+ index += 1;
1399
+ }
1400
+ for (const local of locals) {
1401
+ if (local.to < 0)
1402
+ local.to = length;
1403
+ }
1404
+ for (const callable of callableLocals) {
1405
+ if (callable.to < 0)
1406
+ callable.to = length;
1407
+ }
1408
+ return {
1409
+ declarations,
1410
+ loads,
1411
+ uses,
1412
+ locals,
1413
+ callableLocals,
1414
+ flowAssignments,
1415
+ dynamics,
1416
+ interpolatedExtend,
1417
+ interpolatedPlaceholder,
1418
+ interpolatedPlaceholderRanges,
1419
+ lineStarts,
1420
+ };
1421
+ }
1422
+ /**
1423
+ * Editable slice of a member token, relative to the token.
1424
+ * A forward prefix stays outside the slice when the token starts with it, after the `$` of a
1425
+ * variable; `-` and `_` count as one character. Returns null when the prefix does not split off.
1426
+ */
1427
+ export function memberEditSpan(text, prefix) {
1428
+ if (!prefix)
1429
+ return { start: 0, end: text.length };
1430
+ const sigil = text.startsWith("$") ? 1 : 0;
1431
+ const head = text.slice(sigil, sigil + prefix.length);
1432
+ if (head.length !== prefix.length || head.replace(/_/g, "-") !== prefix.replace(/_/g, "-"))
1433
+ return null;
1434
+ return { start: sigil + prefix.length, end: text.length };
1435
+ }
1436
+ //# sourceMappingURL=syntax.js.map