@lzehrung/codegraph 2.3.30 → 2.3.31

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 (51) hide show
  1. package/dist/bin/cli.js +961 -649
  2. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +0 -7
  3. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
  4. package/dist/graphs/symbol-graph-detailed/receiver-calls.js +2 -35
  5. package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
  6. package/dist/impact/call-compatibility/providers/index.d.ts +12 -0
  7. package/dist/impact/call-compatibility/providers/index.d.ts.map +1 -1
  8. package/dist/impact/call-compatibility/providers/index.js +14 -20
  9. package/dist/impact/call-compatibility/providers/index.js.map +1 -1
  10. package/dist/impact/call-compatibility/providers/profiles.d.ts +80 -0
  11. package/dist/impact/call-compatibility/providers/profiles.d.ts.map +1 -0
  12. package/dist/impact/call-compatibility/providers/profiles.js +164 -0
  13. package/dist/impact/call-compatibility/providers/profiles.js.map +1 -0
  14. package/dist/impact/call-compatibility.d.ts.map +1 -1
  15. package/dist/impact/call-compatibility.js +71 -101
  16. package/dist/impact/call-compatibility.js.map +1 -1
  17. package/dist/impact/member-resolution-coverage.d.ts.map +1 -1
  18. package/dist/impact/member-resolution-coverage.js +1 -1
  19. package/dist/impact/member-resolution-coverage.js.map +1 -1
  20. package/dist/indexer/imports/binding-ranges.d.ts +1 -1
  21. package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
  22. package/dist/indexer/imports/import-binding-tables.d.ts +64 -0
  23. package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -0
  24. package/dist/indexer/imports/import-binding-tables.js +419 -0
  25. package/dist/indexer/imports/import-binding-tables.js.map +1 -0
  26. package/dist/indexer/imports/language-specific.d.ts +3 -22
  27. package/dist/indexer/imports/language-specific.d.ts.map +1 -1
  28. package/dist/indexer/imports/language-specific.js +29 -362
  29. package/dist/indexer/imports/language-specific.js.map +1 -1
  30. package/dist/indexer/imports.d.ts.map +1 -1
  31. package/dist/indexer/imports.js +2 -1
  32. package/dist/indexer/imports.js.map +1 -1
  33. package/dist/indexer/navigation-goto.d.ts +1 -1
  34. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  35. package/dist/indexer/navigation-goto.js +3 -2
  36. package/dist/indexer/navigation-goto.js.map +1 -1
  37. package/dist/util/dynamic-import-tables.d.ts +88 -0
  38. package/dist/util/dynamic-import-tables.d.ts.map +1 -0
  39. package/dist/util/dynamic-import-tables.js +100 -0
  40. package/dist/util/dynamic-import-tables.js.map +1 -0
  41. package/dist/util/member-access-tables.d.ts +72 -0
  42. package/dist/util/member-access-tables.d.ts.map +1 -0
  43. package/dist/util/member-access-tables.js +167 -0
  44. package/dist/util/member-access-tables.js.map +1 -0
  45. package/dist/util/member-access.d.ts.map +1 -1
  46. package/dist/util/member-access.js +44 -91
  47. package/dist/util/member-access.js.map +1 -1
  48. package/dist/util/specifiers.d.ts.map +1 -1
  49. package/dist/util/specifiers.js +10 -93
  50. package/dist/util/specifiers.js.map +1 -1
  51. package/package.json +3 -3
package/dist/bin/cli.js CHANGED
@@ -41387,6 +41387,108 @@ var init_angularjs2 = __esm({
41387
41387
  }
41388
41388
  });
41389
41389
 
41390
+ // dist/util/dynamic-import-tables.js
41391
+ function createDynamicImportEntries(folds) {
41392
+ const JS_TS_DYNAMIC_IMPORT_ENTRY = {
41393
+ // Comments are blanked before matching so a `require(...)` inside a comment cannot match;
41394
+ // string literals stay intact because the fold reads their contents.
41395
+ text: stripJsLikeComments,
41396
+ guard: buildJsLikeLiteralMask,
41397
+ shapes: [
41398
+ {
41399
+ pattern: JS_DYNAMIC_PATH_CALL_PATTERN,
41400
+ fold: folds.foldCapturedPath(JS_PATH_FOLD_PROFILE, folds.resolveFoldedPathAgainstBase)
41401
+ },
41402
+ {
41403
+ pattern: JS_DYNAMIC_URL_CALL_PATTERN,
41404
+ fold: ({ match, fromFile }) => {
41405
+ const folded = folds.foldNewUrlArgument(match[1] ?? "", JS_PATH_FOLD_PROFILE);
41406
+ return folded ? folds.resolveFoldedPathAgainstFileDir(folded, fromFile) : null;
41407
+ }
41408
+ }
41409
+ ]
41410
+ };
41411
+ const RUBY_DYNAMIC_IMPORT_ENTRY = {
41412
+ text: (source) => source,
41413
+ guard: (text) => buildTriviaMask(text, "ruby"),
41414
+ shapes: [
41415
+ {
41416
+ // Only the computed `require File.join(__dir__, ...)` form is folded here; bare-string
41417
+ // requires flow through the static pipeline and `$LOAD_PATH` lookups stay external.
41418
+ pattern: RUBY_REQUIRE_FILE_JOIN_PATTERN,
41419
+ fold: folds.foldCapturedPath(RUBY_PATH_FOLD_PROFILE, folds.resolveFoldedPathByConcatenation)
41420
+ }
41421
+ ]
41422
+ };
41423
+ const PHP_DYNAMIC_IMPORT_ENTRY = {
41424
+ text: (source) => source,
41425
+ guard: (text) => buildTriviaMask(text, "php"),
41426
+ shapes: [
41427
+ {
41428
+ // Computed `include`/`require` whose path is a constant chain rooted at `__DIR__` (or
41429
+ // the legacy `dirname(__FILE__)`); plain string operands stay with the static pipeline
41430
+ // and the include-path search stays external.
41431
+ pattern: PHP_COMPUTED_INCLUDE_PATTERN,
41432
+ fold: folds.foldCapturedPath(PHP_PATH_FOLD_PROFILE, folds.resolveFoldedPathByConcatenation)
41433
+ }
41434
+ ]
41435
+ };
41436
+ const PYTHON_DYNAMIC_IMPORT_ENTRY = {
41437
+ text: (source) => source,
41438
+ guard: (text) => buildTriviaMask(text, "python"),
41439
+ prepare: (source) => {
41440
+ const { importlibAliases, importModuleAliases } = folds.collectPythonDynamicImportAliases(source);
41441
+ return { pythonImportlibAliases: importlibAliases, pythonImportModuleAliases: importModuleAliases };
41442
+ },
41443
+ shapes: [
41444
+ {
41445
+ pattern: PYTHON_DYNAMIC_CALL_PREFIX_PATTERN,
41446
+ fold: ({ text, match, preparation }) => folds.foldPythonDynamicModuleArgument(text, match, preparation)
41447
+ }
41448
+ ]
41449
+ };
41450
+ const entries = {
41451
+ js: JS_TS_DYNAMIC_IMPORT_ENTRY,
41452
+ ts: JS_TS_DYNAMIC_IMPORT_ENTRY,
41453
+ python: PYTHON_DYNAMIC_IMPORT_ENTRY,
41454
+ ruby: RUBY_DYNAMIC_IMPORT_ENTRY,
41455
+ php: PHP_DYNAMIC_IMPORT_ENTRY
41456
+ };
41457
+ return entries;
41458
+ }
41459
+ var JS_PATH_FOLD_PROFILE, RUBY_PATH_FOLD_PROFILE, PHP_PATH_FOLD_PROFILE, JS_DYNAMIC_PATH_CALL_PATTERN, JS_DYNAMIC_URL_CALL_PATTERN, RUBY_REQUIRE_FILE_JOIN_PATTERN, PHP_COMPUTED_INCLUDE_PATTERN, PYTHON_DYNAMIC_CALL_PREFIX_PATTERN;
41460
+ var init_dynamic_import_tables = __esm({
41461
+ "dist/util/dynamic-import-tables.js"() {
41462
+ "use strict";
41463
+ init_comments();
41464
+ init_identifiers();
41465
+ init_trivia();
41466
+ JS_PATH_FOLD_PROFILE = {
41467
+ bases: {
41468
+ __dirname: "fileDir",
41469
+ __filename: "filePath",
41470
+ "import.meta.url": "filePath",
41471
+ "process.cwd()": "project"
41472
+ },
41473
+ joinHelpers: ["path.join", "path.resolve"]
41474
+ };
41475
+ RUBY_PATH_FOLD_PROFILE = {
41476
+ bases: { __dir__: "fileDir" },
41477
+ joinHelpers: ["File.join"]
41478
+ };
41479
+ PHP_PATH_FOLD_PROFILE = {
41480
+ bases: { __DIR__: "fileDir", "dirname(__FILE__)": "fileDir" },
41481
+ joinHelpers: [],
41482
+ concat: "."
41483
+ };
41484
+ JS_DYNAMIC_PATH_CALL_PATTERN = /(?<!["'`])\b(?:require|import)\s*\(\s*(path\.(?:join|resolve)\s*\((?:[^()]|\([^()]*\))*\))\s*\)/g;
41485
+ JS_DYNAMIC_URL_CALL_PATTERN = /(?<!["'`])\b(?:require|import)\s*\(\s*(new\s+URL\s*\([^)]*\))\s*\)/g;
41486
+ RUBY_REQUIRE_FILE_JOIN_PATTERN = /(?<![\p{XID_Continue}])require\s*\(?\s*(File\.join\s*\((?:[^()]|\([^()]*\))*\))/gu;
41487
+ PHP_COMPUTED_INCLUDE_PATTERN = /(?<![\p{XID_Continue}$])(?:include_once|include|require_once|require)\b\s*\(?\s*([^;\r\n]*?)\s*\)?\s*;/gu;
41488
+ PYTHON_DYNAMIC_CALL_PREFIX_PATTERN = new RegExp(String.raw`(?<![._\p{XID_Continue}])(${PYTHON_IDENTIFIER_SOURCE})(?:\s*\.\s*(${PYTHON_IDENTIFIER_SOURCE}))?\s*\(\s*(?:name\s*=\s*)?`, "gmu");
41489
+ }
41490
+ });
41491
+
41390
41492
  // dist/util/specifiers.js
41391
41493
  import path30 from "node:path";
41392
41494
  function splitJsTsNamedSpecifiers(namedBlock) {
@@ -41835,89 +41937,19 @@ function extractPythonSpecifiers(source) {
41835
41937
  }
41836
41938
  return out;
41837
41939
  }
41838
- var JS_TS_NAMED_TYPE_SPECIFIER_PATTERN, JS_PATH_FOLD_PROFILE, RUBY_PATH_FOLD_PROFILE, PHP_PATH_FOLD_PROFILE, JOIN_HELPER_PATTERNS, JS_DYNAMIC_PATH_CALL_PATTERN, JS_DYNAMIC_URL_CALL_PATTERN, RUBY_REQUIRE_FILE_JOIN_PATTERN, PHP_COMPUTED_INCLUDE_PATTERN, JS_TS_DYNAMIC_IMPORT_ENTRY, RUBY_DYNAMIC_IMPORT_ENTRY, PHP_DYNAMIC_IMPORT_ENTRY, PYTHON_DOTTED_NAME_SOURCE, PYTHON_IMPORTLIB_ALIAS_PATTERN, PYTHON_IMPORT_MODULE_ALIAS_PATTERN, PYTHON_DYNAMIC_CALL_PREFIX_PATTERN, PYTHON_DYNAMIC_MODULE_PATTERN, PYTHON_FROM_IMPORTLIB_PATTERN, PYTHON_SIMPLE_STRING_ESCAPES, PYTHON_DYNAMIC_IMPORT_ENTRY, DYNAMIC_IMPORT_SPECIFIER_EXTRACTORS;
41940
+ var JS_TS_NAMED_TYPE_SPECIFIER_PATTERN, JOIN_HELPER_PATTERNS, PYTHON_DOTTED_NAME_SOURCE, PYTHON_IMPORTLIB_ALIAS_PATTERN, PYTHON_IMPORT_MODULE_ALIAS_PATTERN, PYTHON_DYNAMIC_MODULE_PATTERN, PYTHON_FROM_IMPORTLIB_PATTERN, PYTHON_SIMPLE_STRING_ESCAPES, DYNAMIC_IMPORT_SPECIFIER_EXTRACTORS;
41839
41941
  var init_specifiers = __esm({
41840
41942
  "dist/util/specifiers.js"() {
41841
41943
  "use strict";
41842
41944
  init_comments();
41945
+ init_dynamic_import_tables();
41843
41946
  init_identifiers();
41844
- init_trivia();
41845
41947
  init_paths();
41846
41948
  JS_TS_NAMED_TYPE_SPECIFIER_PATTERN = new RegExp(String.raw`^type\s+(${ECMASCRIPT_IDENTIFIER_SOURCE})(?:\s+as\s+(${ECMASCRIPT_IDENTIFIER_SOURCE}))?$`, "u");
41847
- JS_PATH_FOLD_PROFILE = {
41848
- bases: {
41849
- __dirname: "fileDir",
41850
- __filename: "filePath",
41851
- "import.meta.url": "filePath",
41852
- "process.cwd()": "project"
41853
- },
41854
- joinHelpers: ["path.join", "path.resolve"]
41855
- };
41856
- RUBY_PATH_FOLD_PROFILE = {
41857
- bases: { __dir__: "fileDir" },
41858
- joinHelpers: ["File.join"]
41859
- };
41860
- PHP_PATH_FOLD_PROFILE = {
41861
- bases: { __DIR__: "fileDir", "dirname(__FILE__)": "fileDir" },
41862
- joinHelpers: [],
41863
- concat: "."
41864
- };
41865
41949
  JOIN_HELPER_PATTERNS = /* @__PURE__ */ new WeakMap();
41866
- JS_DYNAMIC_PATH_CALL_PATTERN = /(?<!["'`])\b(?:require|import)\s*\(\s*(path\.(?:join|resolve)\s*\((?:[^()]|\([^()]*\))*\))\s*\)/g;
41867
- JS_DYNAMIC_URL_CALL_PATTERN = /(?<!["'`])\b(?:require|import)\s*\(\s*(new\s+URL\s*\([^)]*\))\s*\)/g;
41868
- RUBY_REQUIRE_FILE_JOIN_PATTERN = /(?<![\p{XID_Continue}])require\s*\(?\s*(File\.join\s*\((?:[^()]|\([^()]*\))*\))/gu;
41869
- PHP_COMPUTED_INCLUDE_PATTERN = /(?<![\p{XID_Continue}$])(?:include_once|include|require_once|require)\b\s*\(?\s*([^;\r\n]*?)\s*\)?\s*;/gu;
41870
- JS_TS_DYNAMIC_IMPORT_ENTRY = {
41871
- languageId: "js",
41872
- // Comments are blanked before matching so a `require(...)` inside a comment cannot match;
41873
- // string literals stay intact because the fold reads their contents.
41874
- text: stripJsLikeComments,
41875
- guard: buildJsLikeLiteralMask,
41876
- shapes: [
41877
- {
41878
- pattern: JS_DYNAMIC_PATH_CALL_PATTERN,
41879
- fold: foldCapturedPath(JS_PATH_FOLD_PROFILE, resolveFoldedPathAgainstBase)
41880
- },
41881
- {
41882
- pattern: JS_DYNAMIC_URL_CALL_PATTERN,
41883
- fold: ({ match, fromFile }) => {
41884
- const folded = foldNewUrlArgument(match[1] ?? "", JS_PATH_FOLD_PROFILE);
41885
- return folded ? resolveFoldedPathAgainstFileDir(folded, fromFile) : null;
41886
- }
41887
- }
41888
- ]
41889
- };
41890
- RUBY_DYNAMIC_IMPORT_ENTRY = {
41891
- languageId: "ruby",
41892
- text: (source) => source,
41893
- guard: (text) => buildTriviaMask(text, "ruby"),
41894
- shapes: [
41895
- {
41896
- // Only the computed `require File.join(__dir__, ...)` form is folded here; bare-string
41897
- // requires flow through the static pipeline and `$LOAD_PATH` lookups stay external.
41898
- pattern: RUBY_REQUIRE_FILE_JOIN_PATTERN,
41899
- fold: foldCapturedPath(RUBY_PATH_FOLD_PROFILE, resolveFoldedPathByConcatenation)
41900
- }
41901
- ]
41902
- };
41903
- PHP_DYNAMIC_IMPORT_ENTRY = {
41904
- languageId: "php",
41905
- text: (source) => source,
41906
- guard: (text) => buildTriviaMask(text, "php"),
41907
- shapes: [
41908
- {
41909
- // Computed `include`/`require` whose path is a constant chain rooted at `__DIR__` (or
41910
- // the legacy `dirname(__FILE__)`); plain string operands stay with the static pipeline
41911
- // and the include-path search stays external.
41912
- pattern: PHP_COMPUTED_INCLUDE_PATTERN,
41913
- fold: foldCapturedPath(PHP_PATH_FOLD_PROFILE, resolveFoldedPathByConcatenation)
41914
- }
41915
- ]
41916
- };
41917
41950
  PYTHON_DOTTED_NAME_SOURCE = String.raw`${PYTHON_IDENTIFIER_SOURCE}(?:\.${PYTHON_IDENTIFIER_SOURCE})*`;
41918
41951
  PYTHON_IMPORTLIB_ALIAS_PATTERN = new RegExp(String.raw`^importlib(?:\s+as\s+(${PYTHON_IDENTIFIER_SOURCE}))?$`, "u");
41919
41952
  PYTHON_IMPORT_MODULE_ALIAS_PATTERN = new RegExp(String.raw`^import_module(?:\s+as\s+(${PYTHON_IDENTIFIER_SOURCE}))?$`, "u");
41920
- PYTHON_DYNAMIC_CALL_PREFIX_PATTERN = new RegExp(String.raw`(?<![._\p{XID_Continue}])(${PYTHON_IDENTIFIER_SOURCE})(?:\s*\.\s*(${PYTHON_IDENTIFIER_SOURCE}))?\s*\(\s*(?:name\s*=\s*)?`, "gmu");
41921
41953
  PYTHON_DYNAMIC_MODULE_PATTERN = new RegExp(String.raw`^\.*${PYTHON_DOTTED_NAME_SOURCE}$`, "u");
41922
41954
  PYTHON_FROM_IMPORTLIB_PATTERN = /^\s*from\s+importlib\s+import\s+(?:\(([\s\S]*?)\)|([^\r\n;]+))/gmu;
41923
41955
  PYTHON_SIMPLE_STRING_ESCAPES = {
@@ -41932,28 +41964,15 @@ var init_specifiers = __esm({
41932
41964
  t: " ",
41933
41965
  v: "\v"
41934
41966
  };
41935
- PYTHON_DYNAMIC_IMPORT_ENTRY = {
41936
- languageId: "python",
41937
- text: (source) => source,
41938
- guard: (text) => buildTriviaMask(text, "python"),
41939
- prepare: (source) => {
41940
- const { importlibAliases, importModuleAliases } = collectPythonDynamicImportAliases(source);
41941
- return { pythonImportlibAliases: importlibAliases, pythonImportModuleAliases: importModuleAliases };
41942
- },
41943
- shapes: [
41944
- {
41945
- pattern: PYTHON_DYNAMIC_CALL_PREFIX_PATTERN,
41946
- fold: ({ text, match, preparation }) => foldPythonDynamicModuleArgument(text, match, preparation)
41947
- }
41948
- ]
41949
- };
41950
- DYNAMIC_IMPORT_SPECIFIER_EXTRACTORS = {
41951
- js: JS_TS_DYNAMIC_IMPORT_ENTRY,
41952
- ts: JS_TS_DYNAMIC_IMPORT_ENTRY,
41953
- python: PYTHON_DYNAMIC_IMPORT_ENTRY,
41954
- ruby: RUBY_DYNAMIC_IMPORT_ENTRY,
41955
- php: PHP_DYNAMIC_IMPORT_ENTRY
41956
- };
41967
+ DYNAMIC_IMPORT_SPECIFIER_EXTRACTORS = createDynamicImportEntries({
41968
+ foldCapturedPath,
41969
+ foldNewUrlArgument,
41970
+ resolveFoldedPathAgainstBase,
41971
+ resolveFoldedPathAgainstFileDir,
41972
+ resolveFoldedPathByConcatenation,
41973
+ foldPythonDynamicModuleArgument,
41974
+ collectPythonDynamicImportAliases
41975
+ });
41957
41976
  }
41958
41977
  });
41959
41978
 
@@ -46827,6 +46846,418 @@ var init_parse_context = __esm({
46827
46846
  }
46828
46847
  });
46829
46848
 
46849
+ // dist/indexer/imports/import-binding-tables.js
46850
+ function pushCsharpOverride(context, parsed, typeOnly, fromValue, resolved) {
46851
+ if (parsed.alias) {
46852
+ const fromParts = parsed.from.split(".");
46853
+ const imported = fromParts[fromParts.length - 1] ?? parsed.alias;
46854
+ context.pushBinding({
46855
+ kind: "named",
46856
+ local: parsed.alias,
46857
+ imported,
46858
+ from: fromValue,
46859
+ explicitAlias: true,
46860
+ resolved,
46861
+ typeOnly
46862
+ });
46863
+ return;
46864
+ }
46865
+ context.pushBinding({
46866
+ kind: "star",
46867
+ from: fromValue,
46868
+ resolved,
46869
+ typeOnly
46870
+ });
46871
+ }
46872
+ async function applyCsharpStatementOverride(context, normalizedStmt, typeOnly) {
46873
+ const externAlias = normalizedStmt.match(CSHARP_EXTERN_ALIAS_PATTERN)?.[1];
46874
+ if (externAlias) {
46875
+ context.pushBinding({ kind: "namespace", localNS: externAlias, from: externAlias });
46876
+ return true;
46877
+ }
46878
+ const parsed = parseCsharpUsingDirective(normalizedStmt);
46879
+ if (!parsed)
46880
+ return false;
46881
+ const namespaceTargets = await resolveCsharpNamespaceImportPaths(context.projectRoot, parsed.from, context.file);
46882
+ if (parsed.alias && namespaceTargets.length) {
46883
+ context.pushBinding({
46884
+ kind: "namespace",
46885
+ localNS: parsed.alias,
46886
+ from: parsed.from,
46887
+ ...namespaceTargets.length === 1 ? { resolved: namespaceTargets[0].replace(/\\/g, "/") } : {},
46888
+ typeOnly
46889
+ });
46890
+ return true;
46891
+ }
46892
+ let fromValue = parsed.from;
46893
+ let resolved = await context.resolveFrom(fromValue);
46894
+ if (typeof resolved !== "string" && namespaceTargets.length === 1) {
46895
+ resolved = namespaceTargets[0].replace(/\\/g, "/");
46896
+ }
46897
+ if (parsed.alias) {
46898
+ const fromParts = parsed.from.split(".");
46899
+ if (typeof resolved !== "string" && fromParts.length > 1) {
46900
+ const fallbackFrom = fromParts.slice(0, -1).join(".");
46901
+ if (fallbackFrom) {
46902
+ const fallbackResolved = await context.resolveFrom(fallbackFrom);
46903
+ if (typeof fallbackResolved === "string") {
46904
+ fromValue = fallbackFrom;
46905
+ resolved = fallbackResolved;
46906
+ }
46907
+ }
46908
+ }
46909
+ }
46910
+ pushCsharpOverride(context, parsed, typeOnly, fromValue, resolved);
46911
+ return true;
46912
+ }
46913
+ async function applyJavaStatementOverride(context, normalizedStmt, typeOnly) {
46914
+ return await applyJvmStatementOverride(context, normalizedStmt, typeOnly, parseJavaImportStatement, (parsed) => {
46915
+ if (parsed.kind === "named")
46916
+ return parsed.imported;
46917
+ return void 0;
46918
+ });
46919
+ }
46920
+ async function applyKotlinStatementOverride(context, normalizedStmt, typeOnly) {
46921
+ return await applyJvmStatementOverride(context, normalizedStmt, typeOnly, parseKotlinImportStatement, (parsed) => {
46922
+ if (parsed.kind === "named")
46923
+ return parsed.local;
46924
+ return void 0;
46925
+ });
46926
+ }
46927
+ async function applyJvmStatementOverride(context, normalizedStmt, typeOnly, parseStatement, localNameFor) {
46928
+ const parsed = parseStatement(normalizedStmt);
46929
+ if (!parsed)
46930
+ return false;
46931
+ return await pushJvmImportBinding(context, parsed, localNameFor(parsed), typeOnly);
46932
+ }
46933
+ async function pushJvmImportBinding(context, parsed, local, typeOnly) {
46934
+ const resolved = await context.resolveFrom(parsed.from);
46935
+ if (parsed.kind === "star") {
46936
+ context.pushBinding({
46937
+ kind: "star",
46938
+ from: parsed.from,
46939
+ resolved,
46940
+ typeOnly
46941
+ });
46942
+ return true;
46943
+ }
46944
+ context.pushBinding({
46945
+ kind: "named",
46946
+ local: local ?? parsed.imported,
46947
+ imported: parsed.imported,
46948
+ from: parsed.from,
46949
+ ...parsed.explicitAlias ? { explicitAlias: true } : {},
46950
+ resolved,
46951
+ typeOnly
46952
+ });
46953
+ return true;
46954
+ }
46955
+ async function applyRustStatementOverride(context, normalizedStmt, typeOnly, statementStartIndex) {
46956
+ if (isRustTestOnlyStatement(context, normalizedStmt, statementStartIndex))
46957
+ return true;
46958
+ const parsedList = parseRustImportStatements(normalizedStmt);
46959
+ if (!parsedList.length)
46960
+ return false;
46961
+ const seen = new Set(context.getBindings().map(rustBindingKey));
46962
+ await pushParsedRustImports(context, parsedList, typeOnly, statementStartIndex, seen);
46963
+ return true;
46964
+ }
46965
+ async function resolveRustParsedFrom(context, from4, pathAttribute, statementStartIndex) {
46966
+ if (pathAttribute) {
46967
+ const attributed = await resolveRustImportPath(context.projectRoot, context.file, from4, pathAttribute, statementStartIndex);
46968
+ if (attributed)
46969
+ return attributed.replace(/\\/g, "/");
46970
+ return { external: from4 };
46971
+ }
46972
+ return context.resolveFrom(from4);
46973
+ }
46974
+ function rustBindingKey(binding) {
46975
+ const resolved = JSON.stringify(binding.resolved);
46976
+ if (binding.kind === "named")
46977
+ return `named:${binding.local}:${binding.imported}:${binding.from}:${resolved}`;
46978
+ if (binding.kind === "namespace")
46979
+ return `namespace:${binding.localNS}:${binding.from}:${resolved}`;
46980
+ if (binding.kind === "star")
46981
+ return `star:${binding.from}:${resolved}`;
46982
+ return JSON.stringify(binding);
46983
+ }
46984
+ function buildRustBinding(parsed, resolved, typeOnly) {
46985
+ if (parsed.kind === "member") {
46986
+ return {
46987
+ kind: "named",
46988
+ local: parsed.local,
46989
+ imported: parsed.imported,
46990
+ from: parsed.from,
46991
+ ...parsed.explicitAlias ? { explicitAlias: true } : {},
46992
+ resolved,
46993
+ typeOnly
46994
+ };
46995
+ }
46996
+ if (parsed.kind === "module") {
46997
+ return { kind: "namespace", localNS: parsed.local, from: parsed.from, resolved, typeOnly };
46998
+ }
46999
+ return { kind: "star", from: parsed.from, resolved, typeOnly };
47000
+ }
47001
+ async function pushParsedRustImports(context, parsedList, typeOnly, statementStartIndex, seen) {
47002
+ const statementPathAttribute = extractRustModPathAttribute(context.source, void 0, statementStartIndex);
47003
+ for (const parsed of parsedList) {
47004
+ const pathAttribute = parsed.kind === "module" && !parsed.isExternCrate ? parsed.pathAttribute ?? statementPathAttribute : void 0;
47005
+ const resolved = await resolveRustParsedFrom(context, parsed.from, pathAttribute, statementStartIndex);
47006
+ const binding = buildRustBinding(parsed, resolved, typeOnly);
47007
+ const key = rustBindingKey(binding);
47008
+ if (seen.has(key))
47009
+ continue;
47010
+ seen.add(key);
47011
+ context.pushBinding(binding);
47012
+ }
47013
+ }
47014
+ function isRustTestOnlyStatement(context, normalizedStmt, statementStartIndex) {
47015
+ if (context.languageId !== "rust")
47016
+ return false;
47017
+ if (statementStartIndex !== void 0) {
47018
+ const keywordOffset = rustImportKeywordOffset(context.source.slice(statementStartIndex));
47019
+ const keywordIndex = keywordOffset >= 0 ? statementStartIndex + keywordOffset : statementStartIndex;
47020
+ const keywordText = keywordOffset >= 0 ? context.source.slice(keywordIndex) : normalizedStmt;
47021
+ return isRustCfgTestStatement(context.source, keywordText, keywordIndex);
47022
+ }
47023
+ return isRustCfgTestStatement(context.source, normalizedStmt, statementStartIndex);
47024
+ }
47025
+ async function applyPhpStatementOverride(context, normalizedStmt, typeOnly) {
47026
+ const parsed = parsePhpImportStatement(normalizedStmt, context.file);
47027
+ if (!parsed.length)
47028
+ return false;
47029
+ for (const entry of parsed) {
47030
+ if (entry.kind === "include") {
47031
+ const resolved2 = await context.resolveFrom(entry.from);
47032
+ context.pushBinding({
47033
+ kind: "star",
47034
+ from: entry.from,
47035
+ resolved: resolved2,
47036
+ typeOnly,
47037
+ mechanism: "php"
47038
+ });
47039
+ continue;
47040
+ }
47041
+ const resolved = await context.resolveFrom(entry.from, entry.importType);
47042
+ context.pushBinding({
47043
+ kind: "named",
47044
+ local: entry.local,
47045
+ imported: entry.imported,
47046
+ from: entry.from,
47047
+ ...entry.explicitAlias ? { explicitAlias: true } : {},
47048
+ phpImportType: entry.importType,
47049
+ resolved,
47050
+ typeOnly,
47051
+ mechanism: "php"
47052
+ });
47053
+ }
47054
+ return true;
47055
+ }
47056
+ function pushNamedImplicitBinding(context, binding, stmtText, stmtStartIndex, source, alwaysAliased) {
47057
+ if (stmtStartIndex !== void 0 && source !== void 0) {
47058
+ attributeNamedBindingRanges({
47059
+ bindings: [binding],
47060
+ fromIndex: 0,
47061
+ text: maskImportBindingTrivia(stmtText, context.languageId),
47062
+ textStartIndex: stmtStartIndex,
47063
+ source,
47064
+ ...alwaysAliased !== void 0 ? { alwaysAliased } : {}
47065
+ });
47066
+ }
47067
+ context.pushBinding(binding);
47068
+ }
47069
+ function appendJavaImplicitBinding(context, { from: from4, resolved, typeOnly, stmtText, stmtStartIndex, source }) {
47070
+ const parts = from4.split(".");
47071
+ const last = parts[parts.length - 1];
47072
+ if (last === "*") {
47073
+ context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47074
+ } else if (last) {
47075
+ pushNamedImplicitBinding(context, { kind: "named", local: last, imported: last, from: from4, resolved, typeOnly }, stmtText, stmtStartIndex, source, void 0);
47076
+ }
47077
+ }
47078
+ function appendCsharpImplicitBinding(context, { from: from4, resolved, typeOnly, stmtText, stmtStartIndex, source, alias }) {
47079
+ if (alias) {
47080
+ const fromParts = from4.split(".");
47081
+ const imported = fromParts[fromParts.length - 1] ?? alias;
47082
+ pushNamedImplicitBinding(context, { kind: "named", local: alias, imported, from: from4, explicitAlias: true, resolved, typeOnly }, stmtText, stmtStartIndex, source, IMPORT_BINDING_ROWS.csharp.alwaysAliased);
47083
+ } else {
47084
+ context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47085
+ }
47086
+ }
47087
+ function appendRubyImplicitBinding(context, { from: from4, resolved }) {
47088
+ context.pushBinding({ kind: "star", from: from4, resolved });
47089
+ }
47090
+ function appendGoImplicitBinding(context, { from: from4, resolved, alias }) {
47091
+ if (alias === "_")
47092
+ return;
47093
+ if (alias === ".") {
47094
+ context.pushBinding({ kind: "star", from: from4, resolved });
47095
+ return;
47096
+ }
47097
+ if (alias) {
47098
+ context.pushBinding({ kind: "namespace", localNS: alias, from: from4, resolved });
47099
+ return;
47100
+ }
47101
+ const parts = from4.replace(/"/g, "").split("/");
47102
+ const last = parts[parts.length - 1];
47103
+ if (last)
47104
+ context.pushBinding({ kind: "namespace", localNS: last, from: from4, resolved });
47105
+ }
47106
+ function appendRustImplicitBinding(context, { from: from4, resolved, stmtText, stmtStartIndex, source }) {
47107
+ if (stmtText.startsWith("mod ")) {
47108
+ context.pushBinding({ kind: "namespace", localNS: from4, from: from4, resolved });
47109
+ } else {
47110
+ const parts = from4.split("::");
47111
+ const last = parts[parts.length - 1];
47112
+ if (!last)
47113
+ return;
47114
+ if (last === "*") {
47115
+ context.pushBinding({ kind: "star", from: from4, resolved });
47116
+ } else {
47117
+ pushNamedImplicitBinding(context, { kind: "named", local: last, imported: last, from: from4, resolved }, stmtText, stmtStartIndex, source, void 0);
47118
+ }
47119
+ }
47120
+ }
47121
+ function appendKotlinImplicitBinding(context, { from: from4, resolved, typeOnly, stmtText, stmtStartIndex, source, alias, wildcard }) {
47122
+ if (wildcard || from4.endsWith(".*")) {
47123
+ context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47124
+ } else {
47125
+ const parts = from4.split(".");
47126
+ const imported = parts[parts.length - 1];
47127
+ if (imported)
47128
+ pushNamedImplicitBinding(context, {
47129
+ kind: "named",
47130
+ local: alias ?? imported,
47131
+ imported,
47132
+ from: from4,
47133
+ ...alias !== void 0 ? { explicitAlias: true } : {},
47134
+ resolved,
47135
+ typeOnly
47136
+ }, stmtText, stmtStartIndex, source, void 0);
47137
+ }
47138
+ }
47139
+ function appendSwiftImplicitBinding(context, { from: from4, resolved, typeOnly, stmtText, stmtStartIndex, source }) {
47140
+ const parts = from4.split(".");
47141
+ const last = parts[parts.length - 1];
47142
+ if (!last)
47143
+ return;
47144
+ if (parts.length === 1) {
47145
+ context.pushBinding({ kind: "namespace", localNS: last, from: from4, resolved, typeOnly });
47146
+ context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47147
+ } else {
47148
+ pushNamedImplicitBinding(context, { kind: "named", local: last, imported: last, from: from4, resolved, typeOnly }, stmtText, stmtStartIndex, source, void 0);
47149
+ }
47150
+ }
47151
+ function appendZigImplicitBinding(context, { from: from4, resolved, typeOnly, alias }) {
47152
+ if (alias)
47153
+ context.pushBinding({ kind: "namespace", localNS: alias, from: from4, resolved, typeOnly });
47154
+ }
47155
+ function appendIncludeStarImplicitBinding(context, { from: from4, resolved, typeOnly }) {
47156
+ context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47157
+ }
47158
+ var CSHARP_EXTERN_ALIAS_PATTERN, ECMASCRIPT_STATEMENT_OMITTED, ECMASCRIPT_IMPLICIT_OMITTED, STYLESHEET_OMITTED, INCLUDE_STATEMENT_OMITTED, IMPORT_BINDING_ROWS;
47159
+ var init_import_binding_tables = __esm({
47160
+ "dist/indexer/imports/import-binding-tables.js"() {
47161
+ "use strict";
47162
+ init_import_statement_parsers();
47163
+ init_identifiers();
47164
+ init_rust_test_modules();
47165
+ init_csharp2();
47166
+ init_rust2();
47167
+ init_binding_ranges();
47168
+ CSHARP_EXTERN_ALIAS_PATTERN = new RegExp(String.raw`^extern\s+alias\s+(${CSHARP_IDENTIFIER_SOURCE})\s*;$`, "u");
47169
+ ECMASCRIPT_STATEMENT_OMITTED = "ECMAScript import bindings come from native captures and the JS text fallback, not a statement parser override.";
47170
+ ECMASCRIPT_IMPLICIT_OMITTED = "ECMAScript named/default/namespace/star bindings are emitted from native captures; implicit mapping is unused.";
47171
+ STYLESHEET_OMITTED = "Style language; import bindings are graph-only stylesheet specifiers, not this registry.";
47172
+ INCLUDE_STATEMENT_OMITTED = "C/C++ #include bindings are implicit star imports from native captures; there is no statement parser override.";
47173
+ IMPORT_BINDING_ROWS = {
47174
+ adoc: { omittedReason: "AsciiDoc document format; embedded code blocks parse as their own language." },
47175
+ astro: { omittedReason: "Astro document format; scripts parse as js/ts and templates as html." },
47176
+ c: {
47177
+ appendImplicit: appendIncludeStarImplicitBinding,
47178
+ statementOmittedReason: INCLUDE_STATEMENT_OMITTED
47179
+ },
47180
+ cpp: {
47181
+ appendImplicit: appendIncludeStarImplicitBinding,
47182
+ statementOmittedReason: INCLUDE_STATEMENT_OMITTED
47183
+ },
47184
+ css: { omittedReason: STYLESHEET_OMITTED },
47185
+ csharp: {
47186
+ applyStatement: applyCsharpStatementOverride,
47187
+ appendImplicit: appendCsharpImplicitBinding,
47188
+ maskTrivia: true,
47189
+ normalizeDots: true,
47190
+ alwaysAliased: true
47191
+ },
47192
+ go: {
47193
+ appendImplicit: appendGoImplicitBinding,
47194
+ statementOmittedReason: "Go import bindings come from native captures plus implicit alias/blank/dot mapping; there is no statement parser override."
47195
+ },
47196
+ hbs: { omittedReason: "Handlebars document format; embedded scripts parse as their own language." },
47197
+ html: { omittedReason: "Document format; embedded scripts parse as their own language." },
47198
+ java: {
47199
+ applyStatement: applyJavaStatementOverride,
47200
+ appendImplicit: appendJavaImplicitBinding,
47201
+ maskTrivia: true,
47202
+ normalizeDots: true
47203
+ },
47204
+ js: {
47205
+ statementOmittedReason: ECMASCRIPT_STATEMENT_OMITTED,
47206
+ implicitOmittedReason: ECMASCRIPT_IMPLICIT_OMITTED
47207
+ },
47208
+ kotlin: {
47209
+ applyStatement: applyKotlinStatementOverride,
47210
+ appendImplicit: appendKotlinImplicitBinding,
47211
+ maskTrivia: true,
47212
+ normalizeDots: true
47213
+ },
47214
+ less: { omittedReason: STYLESHEET_OMITTED },
47215
+ markdown: { omittedReason: "Document format; fenced code blocks parse as their own language." },
47216
+ mdx: { omittedReason: "MDX document format; scripts parse as js/ts and templates as html." },
47217
+ php: {
47218
+ applyStatement: applyPhpStatementOverride,
47219
+ maskTrivia: "use-keyword",
47220
+ implicitOmittedReason: "PHP use and include statements are fully handled by the statement override."
47221
+ },
47222
+ python: {
47223
+ omittedReason: "Python import bindings are collected in python.ts, not through statement overrides or implicit mapping."
47224
+ },
47225
+ rst: { omittedReason: "reStructuredText document format; embedded code blocks parse as their own language." },
47226
+ ruby: {
47227
+ appendImplicit: appendRubyImplicitBinding,
47228
+ statementOmittedReason: "Ruby require/load/autoload bindings are implicit star imports from native captures; there is no statement parser override."
47229
+ },
47230
+ rust: {
47231
+ applyStatement: applyRustStatementOverride,
47232
+ appendImplicit: appendRustImplicitBinding,
47233
+ maskTrivia: false,
47234
+ statementKeyUsesOffset: true,
47235
+ rescanTextBindings: true
47236
+ },
47237
+ scss: { omittedReason: STYLESHEET_OMITTED },
47238
+ sql: { omittedReason: "Data language; no import-statement or implicit-binding dispatch." },
47239
+ svelte: { omittedReason: "Svelte component format; script blocks parse as js/ts and templates as html." },
47240
+ swift: {
47241
+ appendImplicit: appendSwiftImplicitBinding,
47242
+ statementOmittedReason: "Swift import bindings are implicit namespace/star (or named) mappings from native captures; there is no statement parser override."
47243
+ },
47244
+ ts: {
47245
+ statementOmittedReason: ECMASCRIPT_STATEMENT_OMITTED,
47246
+ implicitOmittedReason: ECMASCRIPT_IMPLICIT_OMITTED
47247
+ },
47248
+ tsx: {
47249
+ statementOmittedReason: ECMASCRIPT_STATEMENT_OMITTED,
47250
+ implicitOmittedReason: ECMASCRIPT_IMPLICIT_OMITTED
47251
+ },
47252
+ vue: { omittedReason: "Vue component format; script blocks parse as js/ts and templates as html." },
47253
+ zig: {
47254
+ appendImplicit: appendZigImplicitBinding,
47255
+ statementOmittedReason: "Zig @import bindings are implicit namespace mappings from the captured alias; there is no statement parser override."
47256
+ }
47257
+ };
47258
+ }
47259
+ });
47260
+
46830
47261
  // dist/indexer/imports/graph-only.js
46831
47262
  async function collectGraphOnlyImports(context) {
46832
47263
  const entries = Array.from(extractGraphOnlyModuleSpecifiers(context.languageId, context.source));
@@ -47262,7 +47693,8 @@ function normalizeGoImports(context) {
47262
47693
  async function appendTextImportBindings(context) {
47263
47694
  if (!hasTextImportBindings(context.languageId))
47264
47695
  return;
47265
- if (context.languageId !== "rust" && context.getBindings().length)
47696
+ const row = IMPORT_BINDING_ROWS[context.languageId];
47697
+ if (!row?.rescanTextBindings && context.getBindings().length)
47266
47698
  return;
47267
47699
  const state = createStatementImportOverrideState();
47268
47700
  for (const request of collectTextImportBindingRequests(context.languageId, context.source, {
@@ -47278,7 +47710,7 @@ async function appendTextImportBindings(context) {
47278
47710
  text: maskImportBindingTrivia(request.raw, context.languageId),
47279
47711
  textStartIndex: request.start,
47280
47712
  source: context.source,
47281
- ...context.languageId === "csharp" ? { alwaysAliased: true } : {}
47713
+ ...row?.alwaysAliased ? { alwaysAliased: true } : {}
47282
47714
  });
47283
47715
  }
47284
47716
  }
@@ -47312,362 +47744,53 @@ async function finalizeLanguageSpecificImports(context) {
47312
47744
  await appendTextImportBindings(context);
47313
47745
  await appendPhpComposerImplicitImports(context);
47314
47746
  }
47315
- function pushCsharpOverride(context, parsed, typeOnly, fromValue, resolved) {
47316
- if (parsed.alias) {
47317
- const fromParts = parsed.from.split(".");
47318
- const imported = fromParts[fromParts.length - 1] ?? parsed.alias;
47319
- context.pushBinding({
47320
- kind: "named",
47321
- local: parsed.alias,
47322
- imported,
47323
- from: fromValue,
47324
- explicitAlias: true,
47325
- resolved,
47326
- typeOnly
47327
- });
47328
- return;
47329
- }
47330
- context.pushBinding({
47331
- kind: "star",
47332
- from: fromValue,
47333
- resolved,
47334
- typeOnly
47335
- });
47336
- }
47337
- async function applyCsharpStatementOverride(context, normalizedStmt, typeOnly) {
47338
- const externAlias = normalizedStmt.match(CSHARP_EXTERN_ALIAS_PATTERN)?.[1];
47339
- if (externAlias) {
47340
- context.pushBinding({ kind: "namespace", localNS: externAlias, from: externAlias });
47341
- return true;
47342
- }
47343
- const parsed = parseCsharpUsingDirective(normalizedStmt);
47344
- if (!parsed)
47345
- return false;
47346
- const namespaceTargets = await resolveCsharpNamespaceImportPaths(context.projectRoot, parsed.from, context.file);
47347
- if (parsed.alias && namespaceTargets.length) {
47348
- context.pushBinding({
47349
- kind: "namespace",
47350
- localNS: parsed.alias,
47351
- from: parsed.from,
47352
- ...namespaceTargets.length === 1 ? { resolved: namespaceTargets[0].replace(/\\/g, "/") } : {},
47353
- typeOnly
47354
- });
47355
- return true;
47356
- }
47357
- let fromValue = parsed.from;
47358
- let resolved = await context.resolveFrom(fromValue);
47359
- if (typeof resolved !== "string" && namespaceTargets.length === 1) {
47360
- resolved = namespaceTargets[0].replace(/\\/g, "/");
47361
- }
47362
- if (parsed.alias) {
47363
- const fromParts = parsed.from.split(".");
47364
- if (typeof resolved !== "string" && fromParts.length > 1) {
47365
- const fallbackFrom = fromParts.slice(0, -1).join(".");
47366
- if (fallbackFrom) {
47367
- const fallbackResolved = await context.resolveFrom(fallbackFrom);
47368
- if (typeof fallbackResolved === "string") {
47369
- fromValue = fallbackFrom;
47370
- resolved = fallbackResolved;
47371
- }
47372
- }
47373
- }
47374
- }
47375
- pushCsharpOverride(context, parsed, typeOnly, fromValue, resolved);
47376
- return true;
47377
- }
47378
- async function applyJavaStatementOverride(context, normalizedStmt, typeOnly) {
47379
- return await applyJvmStatementOverride(context, normalizedStmt, typeOnly, parseJavaImportStatement, (parsed) => {
47380
- if (parsed.kind === "named")
47381
- return parsed.imported;
47382
- return void 0;
47383
- });
47384
- }
47385
- async function applyKotlinStatementOverride(context, normalizedStmt, typeOnly) {
47386
- return await applyJvmStatementOverride(context, normalizedStmt, typeOnly, parseKotlinImportStatement, (parsed) => {
47387
- if (parsed.kind === "named")
47388
- return parsed.local;
47389
- return void 0;
47390
- });
47391
- }
47392
- async function applyJvmStatementOverride(context, normalizedStmt, typeOnly, parseStatement, localNameFor) {
47393
- const parsed = parseStatement(normalizedStmt);
47394
- if (!parsed)
47395
- return false;
47396
- return await pushJvmImportBinding(context, parsed, localNameFor(parsed), typeOnly);
47397
- }
47398
- async function pushJvmImportBinding(context, parsed, local, typeOnly) {
47399
- const resolved = await context.resolveFrom(parsed.from);
47400
- if (parsed.kind === "star") {
47401
- context.pushBinding({
47402
- kind: "star",
47403
- from: parsed.from,
47404
- resolved,
47405
- typeOnly
47406
- });
47407
- return true;
47408
- }
47409
- context.pushBinding({
47410
- kind: "named",
47411
- local: local ?? parsed.imported,
47412
- imported: parsed.imported,
47413
- from: parsed.from,
47414
- ...parsed.explicitAlias ? { explicitAlias: true } : {},
47415
- resolved,
47416
- typeOnly
47417
- });
47418
- return true;
47419
- }
47420
- async function applyRustStatementOverride(context, normalizedStmt, typeOnly, statementStartIndex) {
47421
- if (isRustTestOnlyStatement(context, normalizedStmt, statementStartIndex))
47422
- return true;
47423
- const parsedList = parseRustImportStatements(normalizedStmt);
47424
- if (!parsedList.length)
47425
- return false;
47426
- const seen = new Set(context.getBindings().map(rustBindingKey));
47427
- await pushParsedRustImports(context, parsedList, typeOnly, statementStartIndex, seen);
47428
- return true;
47429
- }
47430
- async function resolveRustParsedFrom(context, from4, pathAttribute, statementStartIndex) {
47431
- if (pathAttribute) {
47432
- const attributed = await resolveRustImportPath(context.projectRoot, context.file, from4, pathAttribute, statementStartIndex);
47433
- if (attributed)
47434
- return attributed.replace(/\\/g, "/");
47435
- return { external: from4 };
47436
- }
47437
- return context.resolveFrom(from4);
47438
- }
47439
- function rustBindingKey(binding) {
47440
- const resolved = JSON.stringify(binding.resolved);
47441
- if (binding.kind === "named")
47442
- return `named:${binding.local}:${binding.imported}:${binding.from}:${resolved}`;
47443
- if (binding.kind === "namespace")
47444
- return `namespace:${binding.localNS}:${binding.from}:${resolved}`;
47445
- if (binding.kind === "star")
47446
- return `star:${binding.from}:${resolved}`;
47447
- return JSON.stringify(binding);
47448
- }
47449
- function buildRustBinding(parsed, resolved, typeOnly) {
47450
- if (parsed.kind === "member") {
47451
- return {
47452
- kind: "named",
47453
- local: parsed.local,
47454
- imported: parsed.imported,
47455
- from: parsed.from,
47456
- ...parsed.explicitAlias ? { explicitAlias: true } : {},
47457
- resolved,
47458
- typeOnly
47459
- };
47460
- }
47461
- if (parsed.kind === "module") {
47462
- return { kind: "namespace", localNS: parsed.local, from: parsed.from, resolved, typeOnly };
47463
- }
47464
- return { kind: "star", from: parsed.from, resolved, typeOnly };
47465
- }
47466
- async function pushParsedRustImports(context, parsedList, typeOnly, statementStartIndex, seen) {
47467
- const statementPathAttribute = extractRustModPathAttribute(context.source, void 0, statementStartIndex);
47468
- for (const parsed of parsedList) {
47469
- const pathAttribute = parsed.kind === "module" && !parsed.isExternCrate ? parsed.pathAttribute ?? statementPathAttribute : void 0;
47470
- const resolved = await resolveRustParsedFrom(context, parsed.from, pathAttribute, statementStartIndex);
47471
- const binding = buildRustBinding(parsed, resolved, typeOnly);
47472
- const key = rustBindingKey(binding);
47473
- if (seen.has(key))
47474
- continue;
47475
- seen.add(key);
47476
- context.pushBinding(binding);
47477
- }
47478
- }
47479
- function isRustTestOnlyStatement(context, normalizedStmt, statementStartIndex) {
47480
- if (context.languageId !== "rust")
47481
- return false;
47482
- if (statementStartIndex !== void 0) {
47483
- const keywordOffset = rustImportKeywordOffset(context.source.slice(statementStartIndex));
47484
- const keywordIndex = keywordOffset >= 0 ? statementStartIndex + keywordOffset : statementStartIndex;
47485
- const keywordText = keywordOffset >= 0 ? context.source.slice(keywordIndex) : normalizedStmt;
47486
- return isRustCfgTestStatement(context.source, keywordText, keywordIndex);
47487
- }
47488
- return isRustCfgTestStatement(context.source, normalizedStmt, statementStartIndex);
47489
- }
47490
- async function applyPhpStatementOverride(context, normalizedStmt, typeOnly) {
47491
- const parsed = parsePhpImportStatement(normalizedStmt, context.file);
47492
- if (!parsed.length)
47493
- return false;
47494
- for (const entry of parsed) {
47495
- if (entry.kind === "include") {
47496
- const resolved2 = await context.resolveFrom(entry.from);
47497
- context.pushBinding({
47498
- kind: "star",
47499
- from: entry.from,
47500
- resolved: resolved2,
47501
- typeOnly,
47502
- mechanism: "php"
47503
- });
47504
- continue;
47505
- }
47506
- const resolved = await context.resolveFrom(entry.from, entry.importType);
47507
- context.pushBinding({
47508
- kind: "named",
47509
- local: entry.local,
47510
- imported: entry.imported,
47511
- from: entry.from,
47512
- ...entry.explicitAlias ? { explicitAlias: true } : {},
47513
- phpImportType: entry.importType,
47514
- resolved,
47515
- typeOnly,
47516
- mechanism: "php"
47517
- });
47747
+ function masksStatementTrivia(row, normalizedStmt) {
47748
+ if (row.maskTrivia === "use-keyword")
47749
+ return /^\s*use\b/i.test(normalizedStmt);
47750
+ return row.maskTrivia ?? false;
47751
+ }
47752
+ function parserTextForStatement(row, languageId, normalizedStmt) {
47753
+ if (!masksStatementTrivia(row, normalizedStmt))
47754
+ return normalizedStmt;
47755
+ let parserStmt = maskImportBindingTrivia(normalizedStmt, languageId);
47756
+ if (row.normalizeDots)
47757
+ parserStmt = parserStmt.replace(/\s*\.\s*/gu, ".");
47758
+ return parserStmt;
47759
+ }
47760
+ function statementImportOverrideKey(row, normalizedStmt, statementStartIndex) {
47761
+ if (row.statementKeyUsesOffset && statementStartIndex !== void 0) {
47762
+ return `${normalizedStmt}@${statementStartIndex}`;
47518
47763
  }
47519
- return true;
47764
+ return normalizedStmt;
47520
47765
  }
47521
47766
  async function applyStatementImportOverride(context, state, stmtText, typeOnly, statementStartIndex) {
47522
47767
  const normalizedStmt = stmtText.trim();
47523
47768
  if (!normalizedStmt)
47524
47769
  return false;
47525
- const statementKey = statementImportOverrideKey(context.languageId, normalizedStmt, statementStartIndex);
47770
+ const row = IMPORT_BINDING_ROWS[context.languageId];
47771
+ const applyStatement = row?.applyStatement;
47772
+ if (!row || !applyStatement)
47773
+ return false;
47774
+ const statementKey = statementImportOverrideKey(row, normalizedStmt, statementStartIndex);
47526
47775
  if (state.handledStatements.has(statementKey))
47527
47776
  return true;
47528
- let parserStmt = normalizedStmt;
47529
- const canMaskStrings = context.languageId !== "rust" && (context.languageId !== "php" || /^\s*use\b/i.test(normalizedStmt));
47530
- if (canMaskStrings) {
47531
- parserStmt = maskImportBindingTrivia(normalizedStmt, context.languageId);
47532
- if (context.languageId === "csharp" || context.languageId === "java" || context.languageId === "kotlin") {
47533
- parserStmt = parserStmt.replace(/\s*\.\s*/gu, ".");
47534
- }
47535
- }
47536
- let handled = false;
47537
- if (context.languageId === "csharp") {
47538
- handled = await applyCsharpStatementOverride(context, parserStmt, typeOnly);
47539
- } else if (context.languageId === "java") {
47540
- handled = await applyJavaStatementOverride(context, parserStmt, typeOnly);
47541
- } else if (context.languageId === "kotlin") {
47542
- handled = await applyKotlinStatementOverride(context, parserStmt, typeOnly);
47543
- } else if (context.languageId === "rust") {
47544
- handled = await applyRustStatementOverride(context, normalizedStmt, typeOnly, statementStartIndex);
47545
- } else if (context.languageId === "php") {
47546
- handled = await applyPhpStatementOverride(context, parserStmt, typeOnly);
47547
- }
47777
+ const handled = await applyStatement(context, parserTextForStatement(row, context.languageId, normalizedStmt), typeOnly, statementStartIndex);
47548
47778
  if (!handled)
47549
47779
  return false;
47550
47780
  state.handledStatements.add(statementKey);
47551
47781
  return true;
47552
47782
  }
47553
- function statementImportOverrideKey(languageId, normalizedStmt, statementStartIndex) {
47554
- if (languageId === "rust" && statementStartIndex !== void 0) {
47555
- return `${normalizedStmt}@${statementStartIndex}`;
47556
- }
47557
- return normalizedStmt;
47558
- }
47559
47783
  function appendImplicitImportBinding(context, args) {
47560
- const { from: from4, resolved, typeOnly, stmtText, stmtStartIndex, source, alias, wildcard } = args;
47561
- const pushNamed = (binding, alwaysAliased) => pushNamedImplicitBinding(context, binding, stmtText, stmtStartIndex, source, alwaysAliased);
47562
- if (context.languageId === "java") {
47563
- const parts = from4.split(".");
47564
- const last = parts[parts.length - 1];
47565
- if (last === "*") {
47566
- context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47567
- } else if (last) {
47568
- pushNamed({ kind: "named", local: last, imported: last, from: from4, resolved, typeOnly });
47569
- }
47570
- } else if (context.languageId === "csharp") {
47571
- if (alias) {
47572
- const fromParts = from4.split(".");
47573
- const imported = fromParts[fromParts.length - 1] ?? alias;
47574
- pushNamed({ kind: "named", local: alias, imported, from: from4, explicitAlias: true, resolved, typeOnly }, true);
47575
- } else {
47576
- context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47577
- }
47578
- } else if (context.languageId === "ruby") {
47579
- context.pushBinding({ kind: "star", from: from4, resolved });
47580
- } else if (context.languageId === "go") {
47581
- const goAlias = alias;
47582
- if (goAlias === "_")
47583
- return;
47584
- if (goAlias === ".") {
47585
- context.pushBinding({ kind: "star", from: from4, resolved });
47586
- return;
47587
- }
47588
- if (goAlias) {
47589
- context.pushBinding({ kind: "namespace", localNS: goAlias, from: from4, resolved });
47590
- return;
47591
- }
47592
- const parts = from4.replace(/"/g, "").split("/");
47593
- const last = parts[parts.length - 1];
47594
- if (last)
47595
- context.pushBinding({ kind: "namespace", localNS: last, from: from4, resolved });
47596
- } else if (context.languageId === "rust") {
47597
- if (stmtText.startsWith("mod ")) {
47598
- context.pushBinding({ kind: "namespace", localNS: from4, from: from4, resolved });
47599
- } else {
47600
- const parts = from4.split("::");
47601
- const last = parts[parts.length - 1];
47602
- if (!last)
47603
- return;
47604
- if (last === "*") {
47605
- context.pushBinding({ kind: "star", from: from4, resolved });
47606
- } else {
47607
- pushNamed({ kind: "named", local: last, imported: last, from: from4, resolved });
47608
- }
47609
- }
47610
- } else if (context.languageId === "kotlin") {
47611
- if (wildcard || from4.endsWith(".*")) {
47612
- context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47613
- } else {
47614
- const parts = from4.split(".");
47615
- const imported = parts[parts.length - 1];
47616
- if (imported)
47617
- pushNamed({
47618
- kind: "named",
47619
- local: alias ?? imported,
47620
- imported,
47621
- from: from4,
47622
- ...alias !== void 0 ? { explicitAlias: true } : {},
47623
- resolved,
47624
- typeOnly
47625
- });
47626
- }
47627
- } else if (context.languageId === "swift") {
47628
- const parts = from4.split(".");
47629
- const last = parts[parts.length - 1];
47630
- if (!last)
47631
- return;
47632
- if (parts.length === 1) {
47633
- context.pushBinding({ kind: "namespace", localNS: last, from: from4, resolved, typeOnly });
47634
- context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47635
- } else {
47636
- pushNamed({ kind: "named", local: last, imported: last, from: from4, resolved, typeOnly });
47637
- }
47638
- } else if (context.languageId === "zig") {
47639
- if (alias)
47640
- context.pushBinding({ kind: "namespace", localNS: alias, from: from4, resolved, typeOnly });
47641
- } else if (context.languageId === "c" || context.languageId === "cpp") {
47642
- context.pushBinding({ kind: "star", from: from4, resolved, typeOnly });
47643
- }
47644
- }
47645
- function pushNamedImplicitBinding(context, binding, stmtText, stmtStartIndex, source, alwaysAliased) {
47646
- if (stmtStartIndex !== void 0 && source !== void 0) {
47647
- attributeNamedBindingRanges({
47648
- bindings: [binding],
47649
- fromIndex: 0,
47650
- text: maskImportBindingTrivia(stmtText, context.languageId),
47651
- textStartIndex: stmtStartIndex,
47652
- source,
47653
- ...alwaysAliased !== void 0 ? { alwaysAliased } : {}
47654
- });
47655
- }
47656
- context.pushBinding(binding);
47784
+ IMPORT_BINDING_ROWS[context.languageId]?.appendImplicit?.(context, args);
47657
47785
  }
47658
- var CSHARP_EXTERN_ALIAS_PATTERN;
47659
47786
  var init_language_specific = __esm({
47660
47787
  "dist/indexer/imports/language-specific.js"() {
47661
47788
  "use strict";
47662
- init_import_statement_parsers();
47663
47789
  init_identifiers();
47664
- init_rust_test_modules();
47665
47790
  init_resolution();
47666
- init_csharp2();
47667
- init_rust2();
47668
47791
  init_binding_ranges();
47792
+ init_import_binding_tables();
47669
47793
  init_text_import_extractors();
47670
- CSHARP_EXTERN_ALIAS_PATTERN = new RegExp(String.raw`^extern\s+alias\s+(${CSHARP_IDENTIFIER_SOURCE})\s*;$`, "u");
47671
47794
  }
47672
47795
  });
47673
47796
 
@@ -48203,7 +48326,7 @@ async function collectImportsForFile(file2, projectRoot, opts) {
48203
48326
  text: maskImportBindingTrivia(stmtText, resolvedSup.id),
48204
48327
  textStartIndex: statementStartIndex,
48205
48328
  source: resolvedSource,
48206
- alwaysAliased: resolvedSup.id === "csharp"
48329
+ alwaysAliased: IMPORT_BINDING_ROWS[resolvedSup.id]?.alwaysAliased
48207
48330
  });
48208
48331
  }
48209
48332
  return handled;
@@ -48292,6 +48415,7 @@ var init_imports = __esm({
48292
48415
  init_comments();
48293
48416
  init_tree_sitter_native();
48294
48417
  init_binding_ranges();
48418
+ init_import_binding_tables();
48295
48419
  init_graph_only();
48296
48420
  init_js_text_imports();
48297
48421
  init_language_specific();
@@ -62594,15 +62718,166 @@ var init_navigation_local = __esm({
62594
62718
  }
62595
62719
  });
62596
62720
 
62721
+ // dist/util/member-access-tables.js
62722
+ function supportsReceiverMemberNavigation(languageId) {
62723
+ return MEMBER_ACCESS_ROWS[languageId]?.receiverKeywords !== void 0;
62724
+ }
62725
+ function isKeywordReceiver(languageId, receiverName) {
62726
+ const keywords = MEMBER_ACCESS_ROWS[languageId]?.receiverKeywords;
62727
+ if (!keywords)
62728
+ return false;
62729
+ return keywords.own.includes(receiverName) || keywords.supertype.includes(receiverName);
62730
+ }
62731
+ var C_FIELD_ACCESS_SHAPE, CPP_QUALIFIED_ACCESS_SHAPE, THIS_SUPER_RECEIVERS, SELF_RECEIVERS, MEMBER_ACCESS_ROWS, receiverKeywordLanguageIds;
62732
+ var init_member_access_tables = __esm({
62733
+ "dist/util/member-access-tables.js"() {
62734
+ "use strict";
62735
+ C_FIELD_ACCESS_SHAPE = {
62736
+ nodeTypes: ["field_expression"],
62737
+ object: { field: "argument", fallbackIndex: 0 },
62738
+ property: { field: "field", fallbackIndex: 2 }
62739
+ };
62740
+ CPP_QUALIFIED_ACCESS_SHAPE = {
62741
+ nodeTypes: ["qualified_identifier"],
62742
+ object: { field: "scope", fallbackIndex: 0 },
62743
+ property: { field: "name", fallbackIndex: 2 }
62744
+ };
62745
+ THIS_SUPER_RECEIVERS = { own: ["this"], supertype: ["super"] };
62746
+ SELF_RECEIVERS = { own: ["self"], supertype: ["super"] };
62747
+ MEMBER_ACCESS_ROWS = {
62748
+ adoc: { omittedReason: "AsciiDoc document format; embedded code blocks parse as their own language." },
62749
+ astro: { omittedReason: "Astro document format; scripts parse as js/ts and templates as html." },
62750
+ c: {
62751
+ memberAccessShapes: [C_FIELD_ACCESS_SHAPE],
62752
+ receiverKeywordsOmittedReason: "C has no receiver keyword; member access always names an explicit object or pointer."
62753
+ },
62754
+ cpp: {
62755
+ memberAccessShapes: [C_FIELD_ACCESS_SHAPE, CPP_QUALIFIED_ACCESS_SHAPE],
62756
+ receiverKeywords: { own: ["this"], supertype: [] }
62757
+ },
62758
+ css: { omittedReason: "Style language; no member-access concept." },
62759
+ csharp: {
62760
+ memberAccessShapes: [{ object: { index: 0 }, property: { index: 2 } }],
62761
+ receiverKeywords: { own: ["this"], supertype: ["base"] }
62762
+ },
62763
+ go: {
62764
+ extraTraversalTypes: ["qualified_type"],
62765
+ extraMemberAccessTypes: ["qualified_type"],
62766
+ memberAccessShapes: [{ nodeTypes: ["qualified_type"], object: { namedIndex: 0 }, property: { namedIndex: 1 } }],
62767
+ // Go has no receiver keyword: a method call's receiver is an ordinary value. The row still
62768
+ // exists so go receivers must be proven rather than falling back to a bare name.
62769
+ receiverKeywords: { own: [], supertype: [] }
62770
+ },
62771
+ hbs: { omittedReason: "Handlebars document format; embedded scripts parse as their own language." },
62772
+ html: { omittedReason: "Document format; embedded scripts parse as their own language." },
62773
+ java: {
62774
+ memberAccessShapes: [
62775
+ {
62776
+ nodeTypes: ["method_invocation"],
62777
+ object: { field: "object", fallbackIndex: 0 },
62778
+ property: { field: "name", fallbackIndex: 2 }
62779
+ },
62780
+ {
62781
+ nodeTypes: ["scoped_identifier", "scoped_type_identifier"],
62782
+ object: { field: "scope", fallbackIndex: 0 },
62783
+ property: { field: "name", fallbackIndex: 2 }
62784
+ }
62785
+ ],
62786
+ receiverKeywords: THIS_SUPER_RECEIVERS
62787
+ },
62788
+ js: {
62789
+ memberAccessOmittedReason: "The shared generic default already reads member_expression's object and property fields.",
62790
+ receiverKeywords: THIS_SUPER_RECEIVERS
62791
+ },
62792
+ kotlin: {
62793
+ memberAccessShapes: [
62794
+ { nodeTypes: ["navigation_expression"], object: { namedIndex: 0 }, property: { navigation: true } }
62795
+ ],
62796
+ navigationFallbackLastChild: true,
62797
+ receiverKeywords: THIS_SUPER_RECEIVERS
62798
+ },
62799
+ less: { omittedReason: "Style language; no member-access concept." },
62800
+ markdown: { omittedReason: "Document format; fenced code blocks parse as their own language." },
62801
+ mdx: { omittedReason: "MDX document format; scripts parse as js/ts and templates as html." },
62802
+ php: {
62803
+ extraMemberAccessTypes: ["member_call_expression", "nullsafe_member_call_expression", "scoped_call_expression"],
62804
+ memberAccessShapes: [
62805
+ {
62806
+ nodeTypes: ["member_call_expression", "nullsafe_member_call_expression"],
62807
+ object: { field: "object", fallbackIndex: 0 },
62808
+ property: { field: "name", fallbackIndex: 2 }
62809
+ },
62810
+ {
62811
+ nodeTypes: ["scoped_call_expression"],
62812
+ object: { field: "scope", fallbackIndex: 0 },
62813
+ property: { field: "name", fallbackIndex: 2 }
62814
+ }
62815
+ ],
62816
+ receiverKeywords: { own: ["$this", "self", "static"], supertype: ["parent"] }
62817
+ },
62818
+ python: {
62819
+ memberExpressionType: "attribute",
62820
+ memberAccessShapes: [
62821
+ { object: { field: "object", fallbackIndex: 0 }, property: { field: "attribute", fallbackIndex: 2 } }
62822
+ ],
62823
+ receiverKeywords: { own: ["self", "cls"], supertype: [] }
62824
+ },
62825
+ rst: { omittedReason: "reStructuredText document format; embedded code blocks parse as their own language." },
62826
+ ruby: {
62827
+ memberExpressionType: "call",
62828
+ memberAccessShapes: [
62829
+ {
62830
+ nodeTypes: ["scope_resolution"],
62831
+ object: { field: "scope", fallbackIndex: 0 },
62832
+ property: { field: "name", fallbackIndex: 2 }
62833
+ },
62834
+ // Ruby models every other member access as a `call` node with receiver and method fields.
62835
+ { object: { field: "receiver", fallbackIndex: 0 }, property: { field: "method", fallbackIndex: 2 } }
62836
+ ],
62837
+ receiverKeywords: { own: ["self"], supertype: [] }
62838
+ },
62839
+ rust: {
62840
+ memberAccessShapes: [
62841
+ {
62842
+ nodeTypes: ["scoped_identifier"],
62843
+ object: { field: "path", fallbackIndex: 0 },
62844
+ property: { field: "name", fallbackIndex: 2 }
62845
+ }
62846
+ ],
62847
+ receiverKeywords: { own: ["self", "Self"], supertype: [] }
62848
+ },
62849
+ scss: { omittedReason: "Style language; no member-access concept." },
62850
+ svelte: { omittedReason: "Svelte component format; script blocks parse as js/ts and templates as html." },
62851
+ sql: { omittedReason: "Data language; no member-access concept." },
62852
+ swift: {
62853
+ memberAccessShapes: [
62854
+ { nodeTypes: ["navigation_expression"], object: { namedIndex: 0 }, property: { navigation: true } }
62855
+ ],
62856
+ receiverKeywords: SELF_RECEIVERS
62857
+ },
62858
+ ts: {
62859
+ memberAccessOmittedReason: "The shared generic default already reads member_expression's object and property fields.",
62860
+ receiverKeywords: THIS_SUPER_RECEIVERS
62861
+ },
62862
+ tsx: {
62863
+ memberAccessOmittedReason: "The shared generic default already reads member_expression's object and property fields.",
62864
+ receiverKeywords: THIS_SUPER_RECEIVERS
62865
+ },
62866
+ vue: { omittedReason: "Vue component format; script blocks parse as js/ts and templates as html." },
62867
+ zig: {
62868
+ memberAccessOmittedReason: "No per-language extraction today; the shared generic default is zig's behavior.",
62869
+ receiverKeywords: { own: ["self"], supertype: [] }
62870
+ }
62871
+ };
62872
+ receiverKeywordLanguageIds = Object.keys(MEMBER_ACCESS_ROWS).filter((languageId) => MEMBER_ACCESS_ROWS[languageId].receiverKeywords !== void 0);
62873
+ }
62874
+ });
62875
+
62597
62876
  // dist/util/member-access.js
62598
62877
  function memberExpressionTypeFor(sup) {
62599
62878
  if (sup.nodeTypes.memberExpression)
62600
62879
  return sup.nodeTypes.memberExpression;
62601
- if (sup.id === "python")
62602
- return "attribute";
62603
- if (sup.id === "ruby")
62604
- return "call";
62605
- return "member_expression";
62880
+ return MEMBER_ACCESS_ROWS[sup.id]?.memberExpressionType ?? "member_expression";
62606
62881
  }
62607
62882
  function memberPropertyIdentifierTypes(sup) {
62608
62883
  return [...sup.nodeTypes.propertyIdentifier ?? ["property_identifier"]];
@@ -62617,17 +62892,12 @@ function memberAccessTraversalTypes(sup) {
62617
62892
  "subscript_expression",
62618
62893
  "optional_chain"
62619
62894
  ]);
62620
- if (sup.id === "go")
62621
- types.add("qualified_type");
62622
- if (sup.id === "python")
62623
- types.add("attribute");
62624
- if (sup.id === "kotlin" || sup.id === "swift")
62625
- types.add("navigation_expression");
62895
+ for (const nodeType of MEMBER_ACCESS_ROWS[sup.id]?.extraTraversalTypes ?? [])
62896
+ types.add(nodeType);
62626
62897
  return types;
62627
62898
  }
62628
62899
  function isMemberAccessNode(sup, node) {
62629
- const memberExpressionType = memberExpressionTypeFor(sup);
62630
- return node.type === memberExpressionType || sup.id === "go" && node.type === "qualified_type" || sup.id === "php" && (node.type === "member_call_expression" || node.type === "nullsafe_member_call_expression" || node.type === "scoped_call_expression") || node.type === "member_access_expression" || node.type === "qualified_name" || node.type === "field_access" || node.type === "method_invocation" || node.type === "scoped_identifier" || node.type === "scoped_type_identifier" || node.type === "qualified_identifier" || node.type === "call" || node.type === "scope_resolution" || node.type === "field_expression" || node.type === "attribute" || node.type === "navigation_expression";
62900
+ return node.type === memberExpressionTypeFor(sup) || GENERIC_MEMBER_ACCESS_TYPES[node.type] || (MEMBER_ACCESS_ROWS[sup.id]?.extraMemberAccessTypes?.includes(node.type) ?? false);
62631
62901
  }
62632
62902
  function isMemberObjectIdentifier(nodeType) {
62633
62903
  return nodeType === "identifier" || nodeType === "type_identifier" || nodeType === "package_identifier" || nodeType === "constant" || nodeType === "namespace_identifier" || nodeType === "simple_identifier" || nodeType === "instance_variable" || nodeType === "class_variable";
@@ -62645,69 +62915,23 @@ function getNavigationExpressionProperty(sup, expr) {
62645
62915
  const fromSuffix = suffix.childForFieldName("suffix") ?? suffix.childForFieldName("name") ?? suffix.namedChildren[0] ?? suffix.child(0);
62646
62916
  if (fromSuffix)
62647
62917
  return fromSuffix;
62648
- if (sup.id === "kotlin") {
62918
+ if (MEMBER_ACCESS_ROWS[sup.id]?.navigationFallbackLastChild) {
62649
62919
  return expr.namedChildren[expr.namedChildren.length - 1] ?? expr.child(2);
62650
62920
  }
62651
62921
  return null;
62652
62922
  }
62653
- function fieldParts(node, objectField, propertyField) {
62654
- return {
62655
- object: node.childForFieldName(objectField) ?? node.child(0),
62656
- property: node.childForFieldName(propertyField) ?? node.child(2)
62657
- };
62923
+ function shapeChild(memberNode, child) {
62924
+ if ("field" in child)
62925
+ return memberNode.childForFieldName(child.field) ?? memberNode.child(child.fallbackIndex);
62926
+ if ("index" in child)
62927
+ return memberNode.child(child.index);
62928
+ return memberNode.namedChildren[child.namedIndex] ?? memberNode.child(child.namedIndex);
62658
62929
  }
62659
62930
  function getMemberAccessParts(sup, memberNode) {
62660
- if (sup.id === "c" || sup.id === "cpp") {
62661
- if (memberNode.type === "field_expression")
62662
- return fieldParts(memberNode, "argument", "field");
62663
- if (memberNode.type === "qualified_identifier")
62664
- return fieldParts(memberNode, "scope", "name");
62665
- }
62666
- if (sup.id === "python") {
62667
- return fieldParts(memberNode, "object", "attribute");
62668
- }
62669
- if (sup.id === "csharp") {
62670
- return {
62671
- object: memberNode.child(0),
62672
- property: memberNode.child(2)
62673
- };
62674
- }
62675
- if (sup.id === "java") {
62676
- if (memberNode.type === "method_invocation") {
62677
- return fieldParts(memberNode, "object", "name");
62678
- }
62679
- if (memberNode.type === "scoped_identifier" || memberNode.type === "scoped_type_identifier") {
62680
- return fieldParts(memberNode, "scope", "name");
62681
- }
62682
- }
62683
- if (sup.id === "ruby") {
62684
- if (memberNode.type === "scope_resolution") {
62685
- return fieldParts(memberNode, "scope", "name");
62686
- }
62687
- return fieldParts(memberNode, "receiver", "method");
62688
- }
62689
- if (sup.id === "php") {
62690
- if (memberNode.type === "member_call_expression" || memberNode.type === "nullsafe_member_call_expression") {
62691
- return fieldParts(memberNode, "object", "name");
62692
- }
62693
- if (memberNode.type === "scoped_call_expression") {
62694
- return fieldParts(memberNode, "scope", "name");
62695
- }
62696
- }
62697
- if (sup.id === "rust" && memberNode.type === "scoped_identifier") {
62698
- return fieldParts(memberNode, "path", "name");
62699
- }
62700
- if (sup.id === "go" && memberNode.type === "qualified_type") {
62701
- return {
62702
- object: memberNode.namedChildren[0] ?? memberNode.child(0),
62703
- property: memberNode.namedChildren[1] ?? memberNode.child(1)
62704
- };
62705
- }
62706
- if ((sup.id === "kotlin" || sup.id === "swift") && memberNode.type === "navigation_expression") {
62707
- return {
62708
- object: memberNode.namedChildren[0] ?? memberNode.child(0),
62709
- property: getNavigationExpressionProperty(sup, memberNode)
62710
- };
62931
+ const shape = MEMBER_ACCESS_ROWS[sup.id]?.memberAccessShapes?.find((candidate) => candidate.nodeTypes === void 0 || candidate.nodeTypes.includes(memberNode.type));
62932
+ if (shape) {
62933
+ const property = "navigation" in shape.property ? getNavigationExpressionProperty(sup, memberNode) : shapeChild(memberNode, shape.property);
62934
+ return { object: shapeChild(memberNode, shape.object), property };
62711
62935
  }
62712
62936
  return {
62713
62937
  object: memberNode.childForFieldName("object") ?? memberNode.child(0),
@@ -62758,10 +62982,26 @@ function collectMemberAccessChain(args) {
62758
62982
  return null;
62759
62983
  return { base: current, names };
62760
62984
  }
62985
+ var GENERIC_MEMBER_ACCESS_TYPES;
62761
62986
  var init_member_access = __esm({
62762
62987
  "dist/util/member-access.js"() {
62763
62988
  "use strict";
62764
62989
  init_ast();
62990
+ init_member_access_tables();
62991
+ GENERIC_MEMBER_ACCESS_TYPES = {
62992
+ member_access_expression: true,
62993
+ qualified_name: true,
62994
+ field_access: true,
62995
+ method_invocation: true,
62996
+ scoped_identifier: true,
62997
+ scoped_type_identifier: true,
62998
+ qualified_identifier: true,
62999
+ call: true,
63000
+ scope_resolution: true,
63001
+ field_expression: true,
63002
+ attribute: true,
63003
+ navigation_expression: true
63004
+ };
62765
63005
  }
62766
63006
  });
62767
63007
 
@@ -62936,15 +63176,6 @@ var init_ast2 = __esm({
62936
63176
 
62937
63177
  // dist/graphs/symbol-graph-detailed/receiver-calls.js
62938
63178
  import { readFileSync } from "node:fs";
62939
- function supportsReceiverMemberNavigation(languageId) {
62940
- return RECEIVER_KEYWORDS[languageId] !== void 0;
62941
- }
62942
- function isKeywordReceiver(languageId, receiverName) {
62943
- const keywords = RECEIVER_KEYWORDS[languageId];
62944
- if (!keywords)
62945
- return false;
62946
- return keywords.own.includes(receiverName) || keywords.supertype.includes(receiverName);
62947
- }
62948
63179
  function hasStaticMemberDistinction(languageId) {
62949
63180
  return STATIC_MEMBER_LANGUAGES[languageId] !== void 0;
62950
63181
  }
@@ -63338,7 +63569,7 @@ function ownTypeMemberScope(receiverName) {
63338
63569
  return INSTANCE_RECEIVER_KEYWORDS.has(receiverName) ? "instance" : "any";
63339
63570
  }
63340
63571
  function classifyReceiver(sup, receiver, source, proofCache, cacheScope, accessNode) {
63341
- const keywords = RECEIVER_KEYWORDS[sup.id];
63572
+ const keywords = MEMBER_ACCESS_ROWS[sup.id]?.receiverKeywords;
63342
63573
  const text = sliceText(receiver, source).trim();
63343
63574
  if (!text)
63344
63575
  return null;
@@ -63547,34 +63778,16 @@ function provenMemberTarget(graph, membersByOwner, owners, candidate, memberScop
63547
63778
  return { status: "unique", memberId: byArity[0] };
63548
63779
  return { status: "ambiguous" };
63549
63780
  }
63550
- var THIS_SUPER_RECEIVERS, SELF_RECEIVERS, RECEIVER_KEYWORDS, INSTANCE_RECEIVER_KEYWORDS, receiverKeywordLanguageIds, STATIC_MEMBER_LANGUAGES, staticMemberLanguageIds, RECEIVER_CALL_NODE_TYPES, MEMBER_CONTAINER_TYPES, CALL_ARGUMENT_NODE_TYPES, HIERARCHY_LABELS, VALUE_BINDING_TYPES, PARAMETER_LIST_NODE_TYPES, TYPE_SCOPED_ACCESS_TYPES, BINDING_SCOPE_TYPES, BINDING_CONTAINER_TYPES, BINDING_DECLARATION_TYPES, RUBY_CONSTANT_SOURCE, LANGUAGE_CONSTRUCTION_FORMS, MAX_SUPERTYPE_DEPTH;
63781
+ var INSTANCE_RECEIVER_KEYWORDS, STATIC_MEMBER_LANGUAGES, staticMemberLanguageIds, RECEIVER_CALL_NODE_TYPES, MEMBER_CONTAINER_TYPES, CALL_ARGUMENT_NODE_TYPES, HIERARCHY_LABELS, VALUE_BINDING_TYPES, PARAMETER_LIST_NODE_TYPES, TYPE_SCOPED_ACCESS_TYPES, BINDING_SCOPE_TYPES, BINDING_CONTAINER_TYPES, BINDING_DECLARATION_TYPES, RUBY_CONSTANT_SOURCE, LANGUAGE_CONSTRUCTION_FORMS, MAX_SUPERTYPE_DEPTH;
63551
63782
  var init_receiver_calls = __esm({
63552
63783
  "dist/graphs/symbol-graph-detailed/receiver-calls.js"() {
63553
63784
  "use strict";
63554
63785
  init_types2();
63555
63786
  init_ast();
63556
63787
  init_identifiers();
63788
+ init_member_access_tables();
63557
63789
  init_member_access();
63558
- THIS_SUPER_RECEIVERS = { own: ["this"], supertype: ["super"] };
63559
- SELF_RECEIVERS = { own: ["self"], supertype: ["super"] };
63560
- RECEIVER_KEYWORDS = {
63561
- cpp: { own: ["this"], supertype: [] },
63562
- csharp: { own: ["this"], supertype: ["base"] },
63563
- go: { own: [], supertype: [] },
63564
- java: THIS_SUPER_RECEIVERS,
63565
- js: THIS_SUPER_RECEIVERS,
63566
- kotlin: THIS_SUPER_RECEIVERS,
63567
- php: { own: ["$this", "self", "static"], supertype: ["parent"] },
63568
- python: { own: ["self", "cls"], supertype: [] },
63569
- ruby: { own: ["self"], supertype: [] },
63570
- rust: { own: ["self", "Self"], supertype: [] },
63571
- swift: SELF_RECEIVERS,
63572
- ts: THIS_SUPER_RECEIVERS,
63573
- tsx: THIS_SUPER_RECEIVERS,
63574
- zig: { own: ["self"], supertype: [] }
63575
- };
63576
63790
  INSTANCE_RECEIVER_KEYWORDS = /* @__PURE__ */ new Set(["this", "$this"]);
63577
- receiverKeywordLanguageIds = Object.keys(RECEIVER_KEYWORDS);
63578
63791
  STATIC_MEMBER_LANGUAGES = {
63579
63792
  cpp: true,
63580
63793
  csharp: true,
@@ -71575,12 +71788,13 @@ var init_navigation_goto = __esm({
71575
71788
  init_ast();
71576
71789
  init_paths();
71577
71790
  init_member_access();
71791
+ init_member_access_tables();
71578
71792
  init_receiver_calls();
71579
71793
  init_parse_context();
71580
71794
  init_navigation_provenance();
71581
71795
  init_navigation_resolve();
71582
71796
  init_types2();
71583
- init_receiver_calls();
71797
+ init_member_access_tables();
71584
71798
  NESTED_MEMBER_LOCAL_CONTAINERS = /* @__PURE__ */ new Set([
71585
71799
  "block",
71586
71800
  "class",
@@ -74864,7 +75078,151 @@ var init_report = __esm({
74864
75078
  }
74865
75079
  });
74866
75080
 
75081
+ // dist/impact/call-compatibility/providers/profiles.js
75082
+ var CALL_COMPATIBILITY_LANGUAGE_ID_DECLARATIONS, GENERIC_PROFILE, cFamilyProfile, jsFamilyProfile, pythonProfile, rubyProfile, rustProfile, CALL_COMPATIBILITY_LANGUAGE_PROFILES;
75083
+ var init_profiles = __esm({
75084
+ "dist/impact/call-compatibility/providers/profiles.js"() {
75085
+ "use strict";
75086
+ CALL_COMPATIBILITY_LANGUAGE_ID_DECLARATIONS = [
75087
+ "c",
75088
+ "cpp",
75089
+ "csharp",
75090
+ "go",
75091
+ "java",
75092
+ "js",
75093
+ "kotlin",
75094
+ "php",
75095
+ "python",
75096
+ "ruby",
75097
+ "rust",
75098
+ "swift",
75099
+ "ts",
75100
+ "tsx",
75101
+ "zig"
75102
+ ];
75103
+ GENERIC_PROFILE = {
75104
+ receiver: {
75105
+ skipFirst: "always",
75106
+ methodScopeTypes: [],
75107
+ nonMethodScopeTypes: [],
75108
+ firstPositionExact: [],
75109
+ firstPositionTypedPrefixes: [],
75110
+ thisKeyword: null
75111
+ },
75112
+ directParameterChildType: null,
75113
+ parameterSeparators: [],
75114
+ restPrefixes: [],
75115
+ restWordPatterns: [],
75116
+ optionalNameMarker: null,
75117
+ keywordParameterPattern: null,
75118
+ keywordParameterValuePattern: null,
75119
+ zeroSlotParameters: [],
75120
+ signatureCommaScanDetectsRegexLiterals: true,
75121
+ sourceFallback: false,
75122
+ callsiteParenthesesFallback: false,
75123
+ spreadPrefixes: []
75124
+ };
75125
+ cFamilyProfile = {
75126
+ ...GENERIC_PROFILE,
75127
+ zeroSlotParameters: ["void"]
75128
+ };
75129
+ jsFamilyProfile = {
75130
+ ...GENERIC_PROFILE,
75131
+ receiver: {
75132
+ skipFirst: "always",
75133
+ methodScopeTypes: [],
75134
+ nonMethodScopeTypes: [],
75135
+ firstPositionExact: [],
75136
+ firstPositionTypedPrefixes: [],
75137
+ // `this` parameters are receivers at any position.
75138
+ thisKeyword: "this"
75139
+ },
75140
+ // `name?` optional parameters.
75141
+ optionalNameMarker: "?",
75142
+ // The AST path can fail where the source still shows the call, so paren scanning rescues it.
75143
+ sourceFallback: true
75144
+ };
75145
+ pythonProfile = {
75146
+ ...GENERIC_PROFILE,
75147
+ receiver: {
75148
+ // Instance methods drop the receiver; module-level functions keep it as a regular slot.
75149
+ skipFirst: "class-methods",
75150
+ methodScopeTypes: ["class_definition"],
75151
+ nonMethodScopeTypes: ["function_definition"],
75152
+ firstPositionExact: ["self", "cls"],
75153
+ firstPositionTypedPrefixes: ["self:", "cls:"],
75154
+ thisKeyword: null
75155
+ },
75156
+ // `/` (positional-only) and `*` (keyword-only) group markers occupy no slot.
75157
+ parameterSeparators: ["/", "*"],
75158
+ // `*args`/`**kwargs` rest parameters, and the same prefixes make callsites uncountable.
75159
+ restPrefixes: ["*"],
75160
+ spreadPrefixes: ["*"],
75161
+ // `/` is the positional-only separator, so the signature comma-scan cannot treat `/.../` as a regex.
75162
+ signatureCommaScanDetectsRegexLiterals: false
75163
+ };
75164
+ rubyProfile = {
75165
+ ...GENERIC_PROFILE,
75166
+ receiver: {
75167
+ skipFirst: "always",
75168
+ methodScopeTypes: [],
75169
+ nonMethodScopeTypes: [],
75170
+ firstPositionExact: ["self", "cls"],
75171
+ firstPositionTypedPrefixes: ["self:", "cls:"],
75172
+ thisKeyword: null
75173
+ },
75174
+ // `*rest`/`**kw` rest parameters, and the same prefixes make callsites uncountable.
75175
+ restPrefixes: ["*"],
75176
+ spreadPrefixes: ["*"],
75177
+ // `name:` keyword parameters occupy their own slot; `name: value` carries a default and is optional.
75178
+ keywordParameterPattern: /^[A-Za-z_]\w*:/,
75179
+ keywordParameterValuePattern: /^[A-Za-z_]\w*:\s*\S/
75180
+ };
75181
+ rustProfile = {
75182
+ ...GENERIC_PROFILE,
75183
+ receiver: {
75184
+ skipFirst: "always",
75185
+ methodScopeTypes: [],
75186
+ nonMethodScopeTypes: [],
75187
+ firstPositionExact: ["self", "&self", "&mut self"],
75188
+ firstPositionTypedPrefixes: ["self:"],
75189
+ thisKeyword: null
75190
+ }
75191
+ };
75192
+ CALL_COMPATIBILITY_LANGUAGE_PROFILES = {
75193
+ c: cFamilyProfile,
75194
+ cpp: cFamilyProfile,
75195
+ // `params` marks the rest parameter.
75196
+ csharp: { ...GENERIC_PROFILE, restWordPatterns: [/\bparams\b/] },
75197
+ // Trailing `...string` variadics ride the generic top-level ellipsis scan.
75198
+ go: GENERIC_PROFILE,
75199
+ // `String...` variadics ride the generic top-level ellipsis scan; Java has no optional parameters.
75200
+ java: GENERIC_PROFILE,
75201
+ js: jsFamilyProfile,
75202
+ ts: jsFamilyProfile,
75203
+ tsx: jsFamilyProfile,
75204
+ // `vararg` marks the rest parameter.
75205
+ kotlin: { ...GENERIC_PROFILE, restWordPatterns: [/\bvararg\b/] },
75206
+ // `...$rest` spreads ride the generic leading-`...` callsite rule.
75207
+ php: GENERIC_PROFILE,
75208
+ python: pythonProfile,
75209
+ ruby: rubyProfile,
75210
+ rust: rustProfile,
75211
+ // Parameter clauses expose no list node; span the declaration's direct `parameter` children.
75212
+ swift: { ...GENERIC_PROFILE, directParameterChildType: "parameter" },
75213
+ // Callsites expose no argument-list node; scan for the call parentheses instead.
75214
+ zig: { ...GENERIC_PROFILE, callsiteParenthesesFallback: true }
75215
+ };
75216
+ }
75217
+ });
75218
+
74867
75219
  // dist/impact/call-compatibility/providers/index.js
75220
+ function getCallCompatibilityLanguageProfile(languageId) {
75221
+ if (!callCompatibilityLanguageIds.includes(languageId)) {
75222
+ return null;
75223
+ }
75224
+ return CALL_COMPATIBILITY_LANGUAGE_PROFILES[languageId];
75225
+ }
74868
75226
  function registerCallCompatibilityExtractors(extractors) {
74869
75227
  registeredExtractors = extractors;
74870
75228
  }
@@ -74879,29 +75237,13 @@ function getCallCompatibilityProvider(languageId) {
74879
75237
  function getCallCompatibilitySupportedLanguages() {
74880
75238
  return callCompatibilityLanguageIds;
74881
75239
  }
74882
- var CALL_COMPATIBILITY_LANGUAGE_ID_DECLARATIONS, callCompatibilityLanguageIds, registeredExtractors, structuralCallCompatibilityProvider, callCompatibilityProviders;
75240
+ var callCompatibilityLanguageIds, registeredExtractors, structuralCallCompatibilityProvider, callCompatibilityProviders;
74883
75241
  var init_providers = __esm({
74884
75242
  "dist/impact/call-compatibility/providers/index.js"() {
74885
75243
  "use strict";
74886
75244
  init_all();
74887
75245
  init_registry();
74888
- CALL_COMPATIBILITY_LANGUAGE_ID_DECLARATIONS = [
74889
- "c",
74890
- "cpp",
74891
- "csharp",
74892
- "go",
74893
- "java",
74894
- "js",
74895
- "kotlin",
74896
- "php",
74897
- "python",
74898
- "ruby",
74899
- "rust",
74900
- "swift",
74901
- "ts",
74902
- "tsx",
74903
- "zig"
74904
- ];
75246
+ init_profiles();
74905
75247
  callCompatibilityLanguageIds = CALL_COMPATIBILITY_LANGUAGE_ID_DECLARATIONS.filter((languageId) => getLanguageById(languageId) !== void 0);
74906
75248
  registeredExtractors = null;
74907
75249
  structuralCallCompatibilityProvider = {
@@ -76042,41 +76384,23 @@ function hasTopLevelEquals(text) {
76042
76384
  }
76043
76385
  return false;
76044
76386
  }
76045
- function isOptionalParameter(parameter) {
76046
- const colonIndex = parameter.indexOf(":");
76047
- let searchText = parameter;
76048
- if (colonIndex >= 0) {
76049
- searchText = parameter.slice(0, colonIndex);
76050
- }
76051
- return searchText.includes("?") || hasTopLevelEquals(parameter);
76052
- }
76053
- function isThisParameter(parameter) {
76054
- const colonIndex = parameter.indexOf(":");
76055
- if (colonIndex < 0) {
76056
- return parameter.trim() === "this";
76387
+ function shouldSkipFirstReceiverParameter(profile, declaration) {
76388
+ if (profile.receiver.skipFirst !== "class-methods") {
76389
+ return true;
76057
76390
  }
76058
- return parameter.slice(0, colonIndex).trim() === "this";
76059
- }
76060
- function isPythonMethodDeclaration(declaration) {
76061
76391
  let current = declaration.parent;
76062
76392
  while (current) {
76063
- if (current.type === "class_definition") {
76393
+ if (profile.receiver.methodScopeTypes.includes(current.type)) {
76064
76394
  return true;
76065
76395
  }
76066
- if (current.type === "function_definition") {
76396
+ if (profile.receiver.nonMethodScopeTypes.includes(current.type)) {
76067
76397
  return false;
76068
76398
  }
76069
76399
  current = current.parent;
76070
76400
  }
76071
76401
  return false;
76072
76402
  }
76073
- function shouldSkipFirstReceiverParameter(languageId, declaration) {
76074
- if (languageId === "python") {
76075
- return isPythonMethodDeclaration(declaration);
76076
- }
76077
- return true;
76078
- }
76079
- function findSignatureParameterText(request) {
76403
+ function findSignatureParameterText(request, profile) {
76080
76404
  if (!request.tree) {
76081
76405
  return null;
76082
76406
  }
@@ -76085,6 +76409,7 @@ function findSignatureParameterText(request) {
76085
76409
  if (!declaration) {
76086
76410
  return null;
76087
76411
  }
76412
+ const skipFirstReceiver = shouldSkipFirstReceiverParameter(profile, declaration);
76088
76413
  let params = directSignatureParameterNode(declaration);
76089
76414
  if (!params && declaration.type === "variable_declarator") {
76090
76415
  const valueNode = declaration.childForFieldName("value");
@@ -76097,47 +76422,44 @@ function findSignatureParameterText(request) {
76097
76422
  params = findFirstDescendantOfTypes(declaration, parameterListTypes);
76098
76423
  }
76099
76424
  if (!params) {
76100
- if (request.languageId === "swift") {
76101
- const parameterNodes = declaration.namedChildren.filter((child) => child.type === "parameter");
76425
+ const directParameterChildType = profile.directParameterChildType;
76426
+ if (directParameterChildType !== null) {
76427
+ const parameterNodes = declaration.namedChildren.filter((child) => child.type === directParameterChildType);
76102
76428
  const first = parameterNodes[0];
76103
76429
  const last = parameterNodes[parameterNodes.length - 1];
76104
76430
  if (first && last) {
76105
76431
  return {
76106
76432
  text: request.source.slice(first.startIndex, last.endIndex),
76107
- skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration)
76433
+ skipFirstReceiver
76108
76434
  };
76109
76435
  }
76110
76436
  }
76111
- return {
76112
- text: "",
76113
- skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration)
76114
- };
76437
+ return { text: "", skipFirstReceiver };
76115
76438
  }
76116
76439
  const text = request.source.slice(params.startIndex, params.endIndex).trim();
76117
76440
  if (text.startsWith("(") && text.endsWith(")")) {
76118
- return {
76119
- text: text.slice(1, -1),
76120
- skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration)
76121
- };
76441
+ return { text: text.slice(1, -1), skipFirstReceiver };
76122
76442
  }
76123
- return {
76124
- text,
76125
- skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration)
76126
- };
76443
+ return { text, skipFirstReceiver };
76127
76444
  }
76128
- function isReceiverParameter(languageId, parameter, index, skipFirstReceiver) {
76445
+ function isReceiverParameter(profile, parameter, index, skipFirstReceiver) {
76129
76446
  if (!skipFirstReceiver) {
76130
76447
  return false;
76131
76448
  }
76132
76449
  const trimmed = parameter.trim();
76133
- if (!index && (languageId === "python" || languageId === "ruby")) {
76134
- return trimmed === "self" || trimmed === "cls" || trimmed.startsWith("self:") || trimmed.startsWith("cls:");
76135
- }
76136
- if (!index && languageId === "rust") {
76137
- return trimmed === "self" || trimmed === "&self" || trimmed === "&mut self" || trimmed.startsWith("self:");
76450
+ if (!index) {
76451
+ if (profile.receiver.firstPositionExact.includes(trimmed)) {
76452
+ return true;
76453
+ }
76454
+ if (profile.receiver.firstPositionTypedPrefixes.some((prefix) => trimmed.startsWith(prefix))) {
76455
+ return true;
76456
+ }
76138
76457
  }
76139
- if (isJsTsLanguage(languageId)) {
76140
- return isThisParameter(trimmed);
76458
+ const thisKeyword = profile.receiver.thisKeyword;
76459
+ if (thisKeyword !== null) {
76460
+ const colonIndex = trimmed.indexOf(":");
76461
+ const namePortion = colonIndex >= 0 ? trimmed.slice(0, colonIndex).trim() : trimmed;
76462
+ return namePortion === thisKeyword;
76141
76463
  }
76142
76464
  return false;
76143
76465
  }
@@ -76232,11 +76554,7 @@ function hasTopLevelEllipsis(text) {
76232
76554
  }
76233
76555
  return false;
76234
76556
  }
76235
- function isParameterSeparator(languageId, parameter) {
76236
- const trimmed = parameter.trim();
76237
- return languageId === "python" && (trimmed === "/" || trimmed === "*");
76238
- }
76239
- function isRestParameter(languageId, parameter) {
76557
+ function isRestParameter(profile, parameter) {
76240
76558
  const trimmed = parameter.trim();
76241
76559
  if (!trimmed) {
76242
76560
  return false;
@@ -76244,42 +76562,41 @@ function isRestParameter(languageId, parameter) {
76244
76562
  if (hasTopLevelEllipsis(trimmed)) {
76245
76563
  return true;
76246
76564
  }
76247
- if (languageId === "python" || languageId === "ruby") {
76248
- return trimmed.startsWith("*") || trimmed.startsWith("**");
76249
- }
76250
- if (languageId === "csharp") {
76251
- return /\bparams\b/.test(trimmed);
76252
- }
76253
- if (languageId === "kotlin") {
76254
- return /\bvararg\b/.test(trimmed);
76565
+ if (profile.restPrefixes.some((prefix) => trimmed.startsWith(prefix))) {
76566
+ return true;
76255
76567
  }
76256
- return false;
76568
+ return profile.restWordPatterns.some((pattern) => pattern.test(trimmed));
76257
76569
  }
76258
- function isOptionalParameterForLanguage(languageId, parameter) {
76570
+ function isOptionalParameter(profile, parameter) {
76259
76571
  const trimmed = parameter.trim();
76260
76572
  if (!trimmed) {
76261
76573
  return false;
76262
76574
  }
76263
- if (isJsTsLanguage(languageId)) {
76264
- return isOptionalParameter(trimmed);
76575
+ const nameMarker = profile.optionalNameMarker;
76576
+ if (nameMarker !== null) {
76577
+ const colonIndex = trimmed.indexOf(":");
76578
+ const namePortion = colonIndex >= 0 ? trimmed.slice(0, colonIndex) : trimmed;
76579
+ if (namePortion.includes(nameMarker)) {
76580
+ return true;
76581
+ }
76265
76582
  }
76266
- if (languageId === "ruby" && /^[A-Za-z_]\w*:\s*\S/.test(trimmed)) {
76583
+ if (profile.keywordParameterValuePattern?.test(trimmed)) {
76267
76584
  return true;
76268
76585
  }
76269
76586
  return hasTopLevelEquals(trimmed);
76270
76587
  }
76271
- function parameterSlotCount(languageId, parameter) {
76588
+ function parameterSlotCount(profile, parameter) {
76272
76589
  const trimmed = parameter.trim();
76273
76590
  if (!trimmed) {
76274
76591
  return 0;
76275
76592
  }
76276
- if ((languageId === "c" || languageId === "cpp") && trimmed === "void") {
76593
+ if (profile.zeroSlotParameters.includes(trimmed)) {
76277
76594
  return 0;
76278
76595
  }
76279
76596
  return 1;
76280
76597
  }
76281
- function signatureFromParameterText(languageId, parameterText, angleMode, skipFirstReceiver = true) {
76282
- const parameters = splitTopLevelCommaGroups(parameterText, angleMode, languageId !== "python");
76598
+ function signatureFromParameterText(profile, parameterText, angleMode, skipFirstReceiver = true) {
76599
+ const parameters = splitTopLevelCommaGroups(parameterText, angleMode, profile.signatureCommaScanDetectsRegexLiterals);
76283
76600
  if (!parameters) {
76284
76601
  return null;
76285
76602
  }
@@ -76289,41 +76606,42 @@ function signatureFromParameterText(languageId, parameterText, angleMode, skipFi
76289
76606
  let hasRest = false;
76290
76607
  parameters.forEach((parameter, index) => {
76291
76608
  const trimmed = parameter.trim();
76292
- if (!trimmed || isParameterSeparator(languageId, trimmed) || isReceiverParameter(languageId, trimmed, index, skipFirstReceiver)) {
76609
+ if (!trimmed || profile.parameterSeparators.includes(trimmed) || isReceiverParameter(profile, trimmed, index, skipFirstReceiver)) {
76293
76610
  return;
76294
76611
  }
76295
- if (isRestParameter(languageId, trimmed)) {
76612
+ if (isRestParameter(profile, trimmed)) {
76296
76613
  hasRest = true;
76297
76614
  return;
76298
76615
  }
76299
- if (languageId === "ruby" && /^[A-Za-z_]\w*:/.test(trimmed)) {
76616
+ if (profile.keywordParameterPattern?.test(trimmed)) {
76300
76617
  maxArgs += 1;
76301
- if (!isOptionalParameterForLanguage(languageId, trimmed)) {
76618
+ if (!isOptionalParameter(profile, trimmed)) {
76302
76619
  minArgs += 1;
76303
76620
  }
76304
76621
  return;
76305
76622
  }
76306
- const slotCount = parameterSlotCount(languageId, trimmed);
76623
+ const slotCount = parameterSlotCount(profile, trimmed);
76307
76624
  if (!slotCount) {
76308
76625
  return;
76309
76626
  }
76310
76627
  positionalArgCount += slotCount;
76311
76628
  maxArgs += slotCount;
76312
- if (!isOptionalParameterForLanguage(languageId, trimmed)) {
76629
+ if (!isOptionalParameter(profile, trimmed)) {
76313
76630
  minArgs = positionalArgCount;
76314
76631
  }
76315
76632
  });
76316
76633
  return { minArgs, maxArgs: hasRest ? null : maxArgs, confidence: "high" };
76317
76634
  }
76318
76635
  function extractCallableSignatureFromProvider(request) {
76319
- if (!supportsCallCompatibilityLanguage(request.languageId)) {
76636
+ const profile = getCallCompatibilityLanguageProfile(request.languageId);
76637
+ if (!profile) {
76320
76638
  return null;
76321
76639
  }
76322
- const astParameterText = findSignatureParameterText(request);
76640
+ const astParameterText = findSignatureParameterText(request, profile);
76323
76641
  if (astParameterText !== null) {
76324
- return signatureFromParameterText(request.languageId, astParameterText.text, "type-context", astParameterText.skipFirstReceiver);
76642
+ return signatureFromParameterText(profile, astParameterText.text, "type-context", astParameterText.skipFirstReceiver);
76325
76643
  }
76326
- if (!isJsTsLanguage(request.languageId)) {
76644
+ if (!profile.sourceFallback) {
76327
76645
  return null;
76328
76646
  }
76329
76647
  const openIndex = findSignatureOpeningParen(request.source, request.symbolStartIndex);
@@ -76331,17 +76649,18 @@ function extractCallableSignatureFromProvider(request) {
76331
76649
  if (!balanced) {
76332
76650
  return null;
76333
76651
  }
76334
- return signatureFromParameterText(request.languageId, balanced.inner, "type-context");
76652
+ return signatureFromParameterText(profile, balanced.inner, "type-context");
76335
76653
  }
76336
76654
  function extractCallsiteArgumentsFromProvider(request) {
76337
- if (!supportsCallCompatibilityLanguage(request.languageId)) {
76655
+ const profile = getCallCompatibilityLanguageProfile(request.languageId);
76656
+ if (!profile) {
76338
76657
  return null;
76339
76658
  }
76340
- const astArgumentText = findCallsiteArgumentText(request);
76659
+ const astArgumentText = findCallsiteArgumentText(request, profile);
76341
76660
  if (astArgumentText !== null) {
76342
- return callsiteFromArgumentText(request.languageId, astArgumentText.text, astArgumentText.trailingArgumentCount);
76661
+ return callsiteFromArgumentText(profile, astArgumentText.text, astArgumentText.trailingArgumentCount);
76343
76662
  }
76344
- if (!isJsTsLanguage(request.languageId)) {
76663
+ if (!profile.sourceFallback) {
76345
76664
  return null;
76346
76665
  }
76347
76666
  const openIndex = findCallOpeningParen(request.source, request.calleeStartIndex, request.calleeEndIndex);
@@ -76349,7 +76668,7 @@ function extractCallsiteArgumentsFromProvider(request) {
76349
76668
  if (!balanced) {
76350
76669
  return null;
76351
76670
  }
76352
- return callsiteFromArgumentText(request.languageId, balanced.inner);
76671
+ return callsiteFromArgumentText(profile, balanced.inner);
76353
76672
  }
76354
76673
  function extractCallableSignature(request) {
76355
76674
  const provider = getCallCompatibilityProvider(request.languageId);
@@ -76433,7 +76752,7 @@ function countTrailingClosureArguments(text) {
76433
76752
  }
76434
76753
  return count;
76435
76754
  }
76436
- function findCallsiteArgumentText(request) {
76755
+ function findCallsiteArgumentText(request, profile) {
76437
76756
  if (!request.tree) {
76438
76757
  return null;
76439
76758
  }
@@ -76480,33 +76799,27 @@ function findCallsiteArgumentText(request) {
76480
76799
  }
76481
76800
  return { text, trailingArgumentCount };
76482
76801
  }
76483
- if (request.languageId === "zig") {
76802
+ if (profile.callsiteParenthesesFallback) {
76484
76803
  const openIndex = findOpeningParen(request.source, callNode.startIndex);
76485
76804
  const balanced = findBalancedParentheses(request.source, openIndex);
76486
76805
  return balanced ? { text: balanced.inner, trailingArgumentCount: 0 } : null;
76487
76806
  }
76488
76807
  return null;
76489
76808
  }
76490
- function hasUncountableSpreadArgument(languageId, arg) {
76809
+ function hasUncountableSpreadArgument(profile, arg) {
76491
76810
  const trimmed = arg.trim();
76492
76811
  if (trimmed.startsWith("...")) {
76493
76812
  return true;
76494
76813
  }
76495
- if (languageId === "python" || languageId === "ruby") {
76496
- return trimmed.startsWith("*") || trimmed.startsWith("**");
76497
- }
76498
- if (languageId === "php") {
76499
- return trimmed.startsWith("...");
76500
- }
76501
- return false;
76814
+ return profile.spreadPrefixes.some((prefix) => trimmed.startsWith(prefix));
76502
76815
  }
76503
- function callsiteFromArgumentText(languageId, argumentText, trailingArgumentCount = 0) {
76816
+ function callsiteFromArgumentText(profile, argumentText, trailingArgumentCount = 0) {
76504
76817
  const args = splitTopLevelCommaGroups(argumentText, "type-context");
76505
76818
  if (!args) {
76506
76819
  return null;
76507
76820
  }
76508
76821
  for (const arg of args) {
76509
- if (hasUncountableSpreadArgument(languageId, arg)) {
76822
+ if (hasUncountableSpreadArgument(profile, arg)) {
76510
76823
  return null;
76511
76824
  }
76512
76825
  }
@@ -76909,7 +77222,6 @@ var init_call_compatibility = __esm({
76909
77222
  init_parse_context();
76910
77223
  init_types2();
76911
77224
  init_languages();
76912
- init_js_family2();
76913
77225
  init_ast();
76914
77226
  init_paths();
76915
77227
  init_providers();
@@ -76980,7 +77292,7 @@ var init_member_resolution_coverage = __esm({
76980
77292
  "dist/impact/member-resolution-coverage.js"() {
76981
77293
  "use strict";
76982
77294
  init_languages();
76983
- init_receiver_calls();
77295
+ init_member_access_tables();
76984
77296
  init_paths();
76985
77297
  }
76986
77298
  });