@intlayer/lsp 9.7.0 → 9.7.2

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 (49) hide show
  1. package/dist/esm/_virtual/_rolldown/runtime.mjs +5 -6
  2. package/dist/esm/callers/editorCallers.mjs +1 -2
  3. package/dist/esm/callers/index.mjs +2 -3
  4. package/dist/esm/callers/patterns.mjs +2 -3
  5. package/dist/esm/dictionaryUtils.mjs +1 -2
  6. package/dist/esm/findFieldDeclaration.mjs +2 -3
  7. package/dist/esm/findFieldInFile.mjs +1 -2
  8. package/dist/esm/findKeyAtOffset.mjs +1 -2
  9. package/dist/esm/findKeyInContentFile.mjs +1 -2
  10. package/dist/esm/findTCallAtOffset.mjs +1 -2
  11. package/dist/esm/findUsageFieldAtOffset.mjs +1 -2
  12. package/dist/esm/index.mjs +9 -10
  13. package/dist/esm/index.mjs.map +1 -1
  14. package/dist/esm/oxcUtils.mjs +1 -2
  15. package/dist/esm/oxcUtils.mjs.map +1 -1
  16. package/dist/esm/protocol.mjs +1 -2
  17. package/dist/esm/resolveDictionaryTarget.mjs +1 -2
  18. package/dist/esm/usageAnalyzer.mjs +2 -3
  19. package/dist/esm/usageAnalyzer.mjs.map +1 -1
  20. package/dist/esm/utils.mjs +7 -7
  21. package/dist/types/callers/editorCallers.d.ts +0 -2
  22. package/dist/types/callers/editorCallers.d.ts.map +1 -1
  23. package/dist/types/callers/index.d.ts +12 -1
  24. package/dist/types/callers/index.d.ts.map +1 -1
  25. package/dist/types/callers/patterns.d.ts +0 -2
  26. package/dist/types/callers/patterns.d.ts.map +1 -1
  27. package/dist/types/dictionaryUtils.d.ts +0 -2
  28. package/dist/types/dictionaryUtils.d.ts.map +1 -1
  29. package/dist/types/findFieldDeclaration.d.ts +0 -2
  30. package/dist/types/findFieldDeclaration.d.ts.map +1 -1
  31. package/dist/types/findFieldInFile.d.ts +0 -2
  32. package/dist/types/findFieldInFile.d.ts.map +1 -1
  33. package/dist/types/findKeyAtOffset.d.ts +0 -2
  34. package/dist/types/findKeyAtOffset.d.ts.map +1 -1
  35. package/dist/types/findKeyInContentFile.d.ts +1 -2
  36. package/dist/types/findKeyInContentFile.d.ts.map +1 -1
  37. package/dist/types/findTCallAtOffset.d.ts +0 -2
  38. package/dist/types/findTCallAtOffset.d.ts.map +1 -1
  39. package/dist/types/findUsageFieldAtOffset.d.ts +0 -2
  40. package/dist/types/findUsageFieldAtOffset.d.ts.map +1 -1
  41. package/dist/types/oxcUtils.d.ts +0 -2
  42. package/dist/types/oxcUtils.d.ts.map +1 -1
  43. package/dist/types/protocol.d.ts +0 -2
  44. package/dist/types/protocol.d.ts.map +1 -1
  45. package/dist/types/resolveDictionaryTarget.d.ts +1 -2
  46. package/dist/types/resolveDictionaryTarget.d.ts.map +1 -1
  47. package/dist/types/usageAnalyzer.d.ts +0 -2
  48. package/dist/types/usageAnalyzer.d.ts.map +1 -1
  49. package/package.json +42 -42
@@ -1 +1 @@
1
- {"version":3,"file":"usageAnalyzer.mjs","names":["ALL_CALLERS","isCallerActive"],"sources":["../../src/usageAnalyzer.ts"],"sourcesContent":["import {\n ALL_CALLERS,\n type CallerDescriptor,\n type CallerValueSource,\n isCallerActive,\n} from './callers';\nimport { EDITOR_CALLERS } from './callers/editorCallers';\nimport {\n buildParentMap,\n getObjectPropertyNode,\n getObjectPropertyString,\n getPropertyKeyName,\n getStaticStringValue,\n nodeEnd,\n nodeStart,\n type OxcNode,\n parseText,\n walkAst,\n} from './oxcUtils';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** How a message usage appears in source code. */\nexport type MessageUsageKind =\n /** Translation-function or self call: `t('title')`, `formatMessage({ id })`. */\n | 'call'\n /** Member access / bare reference on a content object: `content.title`. */\n | 'member'\n /** Destructured content field: `const { title } = useIntlayer('home')`. */\n | 'destructure'\n /** JSX message component: `<FormattedMessage id=\"home.title\" />`. */\n | 'jsx'\n /** Tagged template: lingui's ``t`Hello` ``. */\n | 'tagged-template'\n /** The caller call itself (dictionary-level usage): `useIntlayer('home')`. */\n | 'namespace';\n\n/**\n * One resolved translation usage inside a source file: which dictionary and\n * field it reads, and the text span it occupies.\n */\nexport type MessageUsage = {\n /** The intlayer dictionary key the usage reads from. */\n dictionaryKey: string;\n /**\n * Path of content fields from the dictionary root. Empty for\n * dictionary-level usages (`namespace` kind, or a bare content variable).\n */\n fieldPath: string[];\n /**\n * Spans of each `fieldPath` segment, aligned by index, when the segments\n * are addressable in source (member chains). Used to trim the path to the\n * segment under the cursor.\n */\n fieldSpans?: { start: number; end: number }[];\n /** Start offset of the usage expression. */\n start: number;\n /** End offset of the usage expression. */\n end: number;\n kind: MessageUsageKind;\n /** The caller that produced the usage, e.g. `'useTranslations'`. */\n callerName: string;\n /** The library the caller belongs to, e.g. `'next-intl'` or `'intlayer'`. */\n library: string;\n /** Module specifier the caller was imported from, when resolvable. */\n moduleSource?: string;\n /**\n * `true` for `member` usages that are a bare reference to a bound variable\n * (`{greet}` in JSX after `const { greet } = useIntlayer(…)`) — the field\n * name itself is not spelled at the usage site. Excluded from\n * find-references results but kept for decorations and hover.\n */\n isBareReference?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Internal binding models\n// ---------------------------------------------------------------------------\n\n/**\n * Variable holding a translation function (`t`) with a bound namespace.\n * `dictionaryKey` is `null` for root-scope translators (`useTranslations()`\n * without a namespace) — the dictionary is then the first dot-segment of\n * each message id.\n */\ntype TranslatorBinding = BindingScope & {\n dictionaryKey: string | null;\n keyPrefix: string[];\n descriptor: CallerDescriptor;\n moduleSource?: string;\n};\n\n/** Variable holding dictionary content (or a field subtree of it). */\ntype ContentBinding = BindingScope & {\n dictionaryKey: string;\n basePath: string[];\n descriptor: CallerDescriptor;\n moduleSource?: string;\n};\n\n/**\n * Where a binding is visible. Two components in the same file routinely bind\n * the same variable name to different dictionaries:\n *\n * const Page = () => { const content = useIntlayer('benchmark'); … }\n * const App = () => { const content = useIntlayer('app'); … }\n *\n * Without a scope, the second declaration would shadow the first and every\n * usage in the file would resolve to the last dictionary declared.\n */\ntype BindingScope = {\n /** Span of the function (or the program) the declaration lives in. */\n scopeStart: number;\n scopeEnd: number;\n /** End offset of the declaration itself — usages before it are not bound. */\n declarationEnd: number;\n};\n\n/**\n * Property names that are framework accessors rather than content fields\n * (react `.value`, vue refs `.value`, editor `.raw`/`.use`): they are skipped\n * when building field paths.\n */\nconst ACCESSOR_PROPERTY_NAMES = new Set(['value', 'raw', 'use']);\n\n/** The shared registry plus the callers only the editor tooling resolves. */\nconst ANALYZED_CALLERS: CallerDescriptor[] = [\n ...ALL_CALLERS,\n ...EDITOR_CALLERS,\n];\n\n// ---------------------------------------------------------------------------\n// Match helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a value source against a call expression's arguments.\n */\nconst readValueSource = (\n callNode: OxcNode,\n source: CallerValueSource\n): string | null => {\n const argumentsList = callNode['arguments'] as OxcNode[] | undefined;\n\n switch (source.from) {\n case 'argument':\n return getStaticStringValue(argumentsList?.[source.index]);\n case 'option':\n return getObjectPropertyString(\n argumentsList?.[source.argumentIndex],\n source.property\n );\n case 'fixed':\n return source.value;\n case 'path-first-segment':\n // Resolved from the message id at usage time, not from the call shape.\n return null;\n }\n};\n\n/** Read the first matching value from a list of sources. */\nconst readValueSources = (\n callNode: OxcNode,\n sources: CallerValueSource[] | undefined\n): string | null => {\n for (const source of sources ?? []) {\n const value = readValueSource(callNode, source);\n\n if (value !== null) return value;\n }\n\n return null;\n};\n\n/**\n * Apply nested-namespace semantics: for descriptors flagged\n * `nestedNamespace`, a dotted namespace is split at the first `.` into the\n * dictionary key and a key-prefix path (next-intl:\n * `useTranslations('about.counter')` → dictionary `about`, prefix\n * `['counter']`).\n */\nconst splitNestedNamespace = (\n descriptor: CallerDescriptor,\n rawNamespace: string\n): { dictionaryKey: string; prefixPath: string[] } => {\n if (!descriptor.nestedNamespace || !rawNamespace.includes('.')) {\n return { dictionaryKey: rawNamespace, prefixPath: [] };\n }\n\n const segments = rawNamespace.split('.');\n\n return { dictionaryKey: segments[0]!, prefixPath: segments.slice(1) };\n};\n\n/**\n * Return the caller name matched by a call/tagged-template callee: the bare\n * identifier name, or the property name of a member expression when the\n * descriptor allows method matching.\n */\nconst getCalleeName = (\n calleeNode: OxcNode | undefined\n): { name: string; isMethod: boolean } | null => {\n if (!calleeNode) return null;\n\n if (calleeNode['type'] === 'Identifier') {\n return { name: calleeNode['name'] as string, isMethod: false };\n }\n\n if (\n calleeNode['type'] === 'MemberExpression' &&\n calleeNode['computed'] !== true\n ) {\n const propertyNode = calleeNode['property'] as OxcNode | undefined;\n\n if (propertyNode?.['type'] === 'Identifier') {\n return { name: propertyNode['name'] as string, isMethod: true };\n }\n }\n\n return null;\n};\n\n/**\n * The message id of a self caller: either the first string argument or the\n * `id` property of a descriptor-object first argument\n * (`formatMessage({ id: 'home.title' })`, `i18n._({ id: '…' })`).\n */\nconst getSelfCallMessageId = (callNode: OxcNode): string | null => {\n const argumentsList = callNode['arguments'] as OxcNode[] | undefined;\n const firstArgument = argumentsList?.[0];\n\n if (!firstArgument) return null;\n\n return (\n getStaticStringValue(firstArgument) ??\n getObjectPropertyString(firstArgument, 'id')\n );\n};\n\n/**\n * Split a message id into dictionary key + field path according to the\n * descriptor semantics.\n */\nconst resolveMessageId = (\n descriptor: CallerDescriptor,\n fixedDictionaryKey: string | null,\n messageId: string\n): { dictionaryKey: string; fieldPath: string[] } | null => {\n if (fixedDictionaryKey !== null) {\n return {\n dictionaryKey: fixedDictionaryKey,\n fieldPath: descriptor.flatKey ? [messageId] : messageId.split('.'),\n };\n }\n\n const usesPathFirstSegment = descriptor.namespaceSources.some(\n (source) => source.from === 'path-first-segment'\n );\n\n if (!usesPathFirstSegment) return null;\n\n const segments = messageId.split('.');\n\n if (!segments[0]) return null;\n\n // A single-segment id names no dictionary: it lives in the library's\n // whole-file catalog (lingui's `messages`), id kept intact.\n if (segments.length === 1) {\n const rootDictionaryKey = getLibraryRootDictionaryKey(descriptor.library);\n\n return rootDictionaryKey\n ? { dictionaryKey: rootDictionaryKey, fieldPath: [messageId] }\n : { dictionaryKey: segments[0], fieldPath: [] };\n }\n\n return { dictionaryKey: segments[0], fieldPath: segments.slice(1) };\n};\n\n/**\n * Split a namespace-less message id at its first dot: the first segment is the\n * dictionary key, the rest the field path (`'home.hero.title'` → `home`,\n * `['hero', 'title']`).\n */\nconst splitMessageIdAtFirstSegment = (\n messageId: string\n): { dictionaryKey: string; fieldPath: string[] } | null => {\n const [dictionaryKey, ...fieldPath] = messageId.split('.');\n\n return dictionaryKey ? { dictionaryKey, fieldPath } : null;\n};\n\n/**\n * The whole-file catalog a library falls back to when an id-derived key names\n * no dictionary, declared on any of its callers (`useLingui` → `messages`).\n */\nexport const getLibraryRootDictionaryKey = (\n library: CallerDescriptor['library']\n): string | undefined =>\n ALL_CALLERS.find(\n (candidate) =>\n candidate.library === library && candidate.rootDictionaryKey !== undefined\n )?.rootDictionaryKey;\n\n/**\n * i18next-style `ns:key` ids override the bound namespace:\n * `t('about:title')` reads the `about` dictionary even when the translator\n * was created with another namespace.\n */\nconst splitNamespacePrefixedId = (\n messageId: string\n): { namespaceOverride: string | null; messagePath: string } => {\n const separatorIndex = messageId.indexOf(':');\n\n if (separatorIndex <= 0) {\n return { namespaceOverride: null, messagePath: messageId };\n }\n\n return {\n namespaceOverride: messageId.slice(0, separatorIndex),\n messagePath: messageId.slice(separatorIndex + 1),\n };\n};\n\n// ---------------------------------------------------------------------------\n// Analyzer\n// ---------------------------------------------------------------------------\n\n/** Unwrap `await expression` down to the awaited expression. */\nconst unwrapAwait = (node: OxcNode | undefined): OxcNode | undefined =>\n node?.['type'] === 'AwaitExpression'\n ? (node['argument'] as OxcNode | undefined)\n : node;\n\n/** Collect every module specifier imported by the program. */\nconst collectImportSources = (program: OxcNode): Set<string> => {\n const importSources = new Set<string>();\n\n for (const statement of (program['body'] as OxcNode[]) ?? []) {\n if (statement['type'] !== 'ImportDeclaration') continue;\n const sourceValue = (statement['source'] as OxcNode | undefined)?.['value'];\n\n if (typeof sourceValue === 'string') importSources.add(sourceValue);\n }\n\n return importSources;\n};\n\n/** Map each imported local name to its module specifier. */\nconst collectImportedLocalNames = (program: OxcNode): Map<string, string> => {\n const localNameToSource = new Map<string, string>();\n\n for (const statement of (program['body'] as OxcNode[]) ?? []) {\n if (statement['type'] !== 'ImportDeclaration') continue;\n const sourceValue = (statement['source'] as OxcNode | undefined)?.['value'];\n\n if (typeof sourceValue !== 'string') continue;\n\n for (const specifier of (statement['specifiers'] as OxcNode[]) ?? []) {\n const localName = (specifier['local'] as OxcNode | undefined)?.['name'];\n\n if (typeof localName === 'string') {\n localNameToSource.set(localName, sourceValue);\n }\n }\n }\n\n return localNameToSource;\n};\n\ntype AnalyzerState = {\n usages: MessageUsage[];\n /** Bindings are keyed by variable name, then by declaration (see BindingScope). */\n translatorBindings: Map<string, TranslatorBinding[]>;\n contentBindings: Map<string, ContentBinding[]>;\n activeDescriptors: CallerDescriptor[];\n importedLocalNames: Map<string, string>;\n parentMap: Map<OxcNode, OxcNode>;\n program: OxcNode;\n};\n\n/** Node types that open a new binding scope. */\nconst SCOPE_NODE_TYPES = new Set([\n 'FunctionDeclaration',\n 'FunctionExpression',\n 'ArrowFunctionExpression',\n 'ClassMethod',\n 'ObjectMethod',\n 'StaticBlock',\n 'Program',\n]);\n\n/**\n * Span of the nearest enclosing function — the region a declaration is\n * visible in. Falls back to the whole program for module-level declarations.\n */\nconst getEnclosingScope = (\n state: AnalyzerState,\n node: OxcNode\n): { scopeStart: number; scopeEnd: number } => {\n let current: OxcNode | undefined = node;\n\n while (current) {\n if (SCOPE_NODE_TYPES.has(current['type'] as string)) {\n return { scopeStart: nodeStart(current), scopeEnd: nodeEnd(current) };\n }\n current = state.parentMap.get(current);\n }\n\n return {\n scopeStart: nodeStart(state.program),\n scopeEnd: nodeEnd(state.program),\n };\n};\n\nconst addBinding = <T>(\n bindings: Map<string, T[]>,\n variableName: string,\n binding: T\n): void => {\n const existing = bindings.get(variableName);\n\n if (existing) {\n existing.push(binding);\n } else {\n bindings.set(variableName, [binding]);\n }\n};\n\n/**\n * The binding a variable resolves to at `offset`: the innermost scope that\n * contains the offset, among declarations that precede it.\n */\nconst resolveBinding = <T extends BindingScope>(\n bindings: Map<string, T[]>,\n variableName: string,\n offset: number\n): T | undefined => {\n const candidates = bindings.get(variableName);\n\n if (!candidates) return undefined;\n\n let best: T | undefined;\n\n for (const candidate of candidates) {\n if (offset < candidate.scopeStart || offset > candidate.scopeEnd) continue;\n\n // A usage textually before its declaration belongs to an outer binding.\n if (offset < candidate.declarationEnd) continue;\n\n // Innermost scope wins; on equal scopes the latest declaration wins.\n if (\n !best ||\n candidate.scopeStart > best.scopeStart ||\n (candidate.scopeStart === best.scopeStart &&\n candidate.declarationEnd > best.declarationEnd)\n ) {\n best = candidate;\n }\n }\n\n return best;\n};\n\n/**\n * Find the descriptor matching a call (or tagged template) callee among the\n * active descriptors.\n */\nconst matchDescriptorForCallee = (\n state: AnalyzerState,\n calleeNode: OxcNode | undefined,\n filter?: (descriptor: CallerDescriptor) => boolean\n): CallerDescriptor | null => {\n const callee = getCalleeName(calleeNode);\n\n if (!callee) return null;\n\n // An imported store read through `$` takes precedence over a caller that\n // happens to share the prefixed name (svelte-i18n `$t` vs vue-i18n `$t`).\n const storeName = getSvelteStoreName(state, callee);\n const calleeNames = storeName ? [storeName, callee.name] : [callee.name];\n\n for (const calleeName of calleeNames) {\n for (const descriptor of state.activeDescriptors) {\n if (descriptor.callerName !== calleeName) continue;\n\n if (callee.isMethod && !descriptor.matchAsMethod) continue;\n\n if (filter && !filter(descriptor)) continue;\n\n return descriptor;\n }\n }\n\n return null;\n};\n\n/**\n * Svelte auto-subscribes an imported store through a `$` prefix:\n * `import { _ } from 'svelte-i18n'` is read as `$_('home.title')`. Returns the\n * store's imported name for such a callee.\n */\nconst getSvelteStoreName = (\n state: AnalyzerState,\n callee: { name: string; isMethod: boolean }\n): string | null => {\n if (callee.isMethod || !callee.name.startsWith('$')) return null;\n\n const storeName = callee.name.slice(1);\n\n return state.importedLocalNames.has(storeName) ? storeName : null;\n};\n\n/** The module specifier a caller local name was imported from, if any. */\nconst getModuleSource = (\n state: AnalyzerState,\n descriptor: CallerDescriptor\n): string | undefined =>\n state.importedLocalNames.get(descriptor.callerName) ?? undefined;\n\n/**\n * Recursively register a content destructure pattern: each property key is a\n * field usage, each bound identifier becomes a content binding, and nested\n * patterns extend the field path.\n *\n * const { searchInput: { text: alias } } = useIntlayer('key')\n * → usages: ['searchInput'], ['searchInput', 'text']\n * → binding: alias → ['searchInput', 'text']\n */\nconst collectContentDestructure = (\n state: AnalyzerState,\n pattern: OxcNode,\n dictionaryKey: string,\n basePath: string[],\n descriptor: CallerDescriptor,\n moduleSource: string | undefined,\n scope: BindingScope\n): void => {\n for (const property of (pattern['properties'] as OxcNode[]) ?? []) {\n const propertyType = property['type'] as string;\n\n if (propertyType !== 'Property' && propertyType !== 'ObjectProperty') {\n continue;\n }\n\n const keyNode = property['key'] as OxcNode | undefined;\n const fieldName = getPropertyKeyName(keyNode);\n\n if (!keyNode || !fieldName) continue;\n\n const fieldPath = [...basePath, fieldName];\n\n state.usages.push({\n dictionaryKey,\n fieldPath,\n start: nodeStart(keyNode),\n end: nodeEnd(keyNode),\n kind: 'destructure',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource,\n });\n\n // Unwrap default values: { title = fallback }\n let valueNode = property['value'] as OxcNode | undefined;\n\n if (valueNode?.['type'] === 'AssignmentPattern') {\n valueNode = valueNode['left'] as OxcNode | undefined;\n }\n\n if (valueNode?.['type'] === 'Identifier') {\n addBinding(state.contentBindings, valueNode['name'] as string, {\n dictionaryKey,\n basePath: fieldPath,\n descriptor,\n moduleSource,\n ...scope,\n });\n } else if (valueNode?.['type'] === 'ObjectPattern') {\n collectContentDestructure(\n state,\n valueNode,\n dictionaryKey,\n fieldPath,\n descriptor,\n moduleSource,\n scope\n );\n }\n }\n};\n\n/**\n * Register bindings created by `const … = caller(…)` declarations, and record\n * dictionary-level (`namespace`) usages for every matched caller call.\n */\nconst collectBindings = (state: AnalyzerState, program: OxcNode): void => {\n walkAst(program, (node) => {\n if (node['type'] === 'CallExpression') {\n const descriptor = matchDescriptorForCallee(\n state,\n node['callee'] as OxcNode | undefined,\n (candidate) => candidate.translationFunction !== 'self'\n );\n\n if (descriptor) {\n const rawNamespace = readValueSources(\n node,\n descriptor.namespaceSources\n );\n\n if (rawNamespace) {\n const { dictionaryKey } = splitNestedNamespace(\n descriptor,\n rawNamespace\n );\n\n state.usages.push({\n dictionaryKey,\n fieldPath: [],\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'namespace',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n }\n }\n return;\n }\n\n if (node['type'] !== 'VariableDeclarator') return;\n\n const initializer = unwrapAwait(node['init'] as OxcNode | undefined);\n\n if (\n initializer?.['type'] === 'ArrowFunctionExpression' ||\n initializer?.['type'] === 'FunctionExpression'\n ) {\n collectPrefixingWrapperBinding(state, node, initializer);\n return;\n }\n\n if (initializer?.['type'] !== 'CallExpression') return;\n\n const descriptor = matchDescriptorForCallee(\n state,\n initializer['callee'] as OxcNode | undefined,\n (candidate) => candidate.translationFunction !== 'self'\n );\n\n if (!descriptor) return;\n\n const rawNamespace = readValueSources(\n initializer,\n descriptor.namespaceSources\n );\n\n // Root scope: `useTranslations()` — the dictionary comes from each id.\n if (!rawNamespace && !descriptor.allowRootScope) return;\n\n const namespaceSplit = rawNamespace\n ? splitNestedNamespace(descriptor, rawNamespace)\n : { dictionaryKey: null, prefixPath: [] };\n\n const keyPrefixValue = readValueSources(\n initializer,\n descriptor.keyPrefixSources\n );\n const keyPrefix = [\n ...namespaceSplit.prefixPath,\n ...(keyPrefixValue ? keyPrefixValue.split('.') : []),\n ];\n const dictionaryKey = namespaceSplit.dictionaryKey;\n const moduleSource = getModuleSource(state, descriptor);\n const idNode = node['id'] as OxcNode | undefined;\n\n if (!idNode) return;\n\n const scope: BindingScope = {\n ...getEnclosingScope(state, node),\n declarationEnd: nodeEnd(node),\n };\n\n // const t = useTranslations('ns') / const content = useIntlayer('key')\n if (idNode['type'] === 'Identifier') {\n const variableName = idNode['name'] as string;\n\n if (descriptor.translationFunction === 'return-value') {\n addBinding(state.translatorBindings, variableName, {\n dictionaryKey,\n keyPrefix,\n descriptor,\n moduleSource,\n ...scope,\n });\n } else if (\n descriptor.translationFunction === 'content' &&\n dictionaryKey\n ) {\n addBinding(state.contentBindings, variableName, {\n dictionaryKey,\n basePath: keyPrefix,\n descriptor,\n moduleSource,\n ...scope,\n });\n }\n return;\n }\n\n // const { t } = useTranslation('ns') / const { title } = useIntlayer('key')\n if (idNode['type'] !== 'ObjectPattern') return;\n\n if (descriptor.translationFunction === 'content') {\n if (!dictionaryKey) return;\n\n collectContentDestructure(\n state,\n idNode,\n dictionaryKey,\n keyPrefix,\n descriptor,\n moduleSource,\n scope\n );\n return;\n }\n\n if (descriptor.translationFunction !== 'destructured-t') return;\n\n for (const property of (idNode['properties'] as OxcNode[]) ?? []) {\n const propertyType = property['type'] as string;\n\n if (propertyType !== 'Property' && propertyType !== 'ObjectProperty') {\n continue;\n }\n\n const keyNode = property['key'] as OxcNode | undefined;\n const valueNode = property['value'] as OxcNode | undefined;\n const fieldName = getPropertyKeyName(keyNode);\n const localName =\n valueNode?.['type'] === 'Identifier'\n ? (valueNode['name'] as string)\n : null;\n\n // Only the `t` property carries the translation function.\n if (fieldName !== 't' || !localName) continue;\n\n addBinding(state.translatorBindings, localName, {\n dictionaryKey,\n keyPrefix,\n descriptor,\n moduleSource,\n ...scope,\n });\n }\n });\n};\n\n/** The single returned expression of a function body, if any. */\nconst getReturnedExpression = (functionNode: OxcNode): OxcNode | undefined => {\n const body = functionNode['body'] as OxcNode | undefined;\n\n if (body?.['type'] !== 'BlockStatement') return body;\n\n const statements = (body['body'] as OxcNode[] | undefined) ?? [];\n const onlyStatement = statements.length === 1 ? statements[0] : undefined;\n\n return onlyStatement?.['type'] === 'ReturnStatement'\n ? (onlyStatement['argument'] as OxcNode | undefined)\n : undefined;\n};\n\n/**\n * The static prefix of a `` `footer.${id}` `` template whose only\n * substitution is `parameterName`, split into path segments.\n */\nconst getTemplatePrefixSegments = (\n templateNode: OxcNode | undefined,\n parameterName: string\n): string[] | null => {\n if (templateNode?.['type'] !== 'TemplateLiteral') return null;\n\n const quasis = (templateNode['quasis'] as OxcNode[] | undefined) ?? [];\n const expressions =\n (templateNode['expressions'] as OxcNode[] | undefined) ?? [];\n const readQuasi = (quasi: OxcNode | undefined): string | undefined => {\n const value = quasi?.['value'] as OxcNode | undefined;\n\n return (value?.['cooked'] as string | undefined) ?? undefined;\n };\n\n if (\n expressions.length !== 1 ||\n expressions[0]?.['type'] !== 'Identifier' ||\n expressions[0]['name'] !== parameterName ||\n readQuasi(quasis[1]) !== ''\n ) {\n return null;\n }\n\n const prefix = readQuasi(quasis[0]);\n\n if (!prefix?.endsWith('.')) return null;\n\n return prefix.slice(0, -1).split('.');\n};\n\n/**\n * Register a local wrapper that prefixes every id before translating it as a\n * translator binding:\n *\n * const t = (id: string) => i18n._(`footer.${id}`); t('github')\n * const tf = (key) => t(`form.${key}`); tf('name')\n */\nconst collectPrefixingWrapperBinding = (\n state: AnalyzerState,\n declaratorNode: OxcNode,\n functionNode: OxcNode\n): void => {\n const idNode = declaratorNode['id'] as OxcNode | undefined;\n const parameterNode = (functionNode['params'] as OxcNode[] | undefined)?.[0];\n const callNode = getReturnedExpression(functionNode);\n\n if (\n idNode?.['type'] !== 'Identifier' ||\n parameterNode?.['type'] !== 'Identifier' ||\n callNode?.['type'] !== 'CallExpression'\n ) {\n return;\n }\n\n const prefixSegments = getTemplatePrefixSegments(\n (callNode['arguments'] as OxcNode[] | undefined)?.[0],\n parameterNode['name'] as string\n );\n\n if (!prefixSegments) return;\n\n const scope: BindingScope = {\n ...getEnclosingScope(state, declaratorNode),\n declarationEnd: nodeEnd(declaratorNode),\n };\n const calleeNode = callNode['callee'] as OxcNode | undefined;\n const wrappedBinding =\n calleeNode?.['type'] === 'Identifier'\n ? resolveBinding(\n state.translatorBindings,\n calleeNode['name'] as string,\n nodeStart(callNode)\n )\n : undefined;\n\n if (wrappedBinding) {\n addBinding(state.translatorBindings, idNode['name'] as string, {\n ...wrappedBinding,\n keyPrefix: [...wrappedBinding.keyPrefix, ...prefixSegments],\n ...scope,\n });\n return;\n }\n\n const descriptor = matchDescriptorForCallee(\n state,\n calleeNode,\n (candidate) => candidate.translationFunction === 'self'\n );\n\n if (!descriptor) return;\n\n addBinding(state.translatorBindings, idNode['name'] as string, {\n // `null` = root scope: the first prefixed segment names the dictionary.\n dictionaryKey: readValueSources(callNode, descriptor.namespaceSources),\n keyPrefix: prefixSegments,\n descriptor,\n moduleSource: getModuleSource(state, descriptor),\n ...scope,\n });\n};\n\n/** Methods of a translation function that take a message id first. */\nconst TRANSLATOR_METHOD_NAMES = new Set(['rich', 'markup', 'raw', 'has']);\n\n/**\n * The translator identifier a call goes through: `t` in `t('id')` and in\n * `t.rich('id')`.\n */\nconst getTranslatorCalleeIdentifier = (\n calleeNode: OxcNode | undefined\n): OxcNode | null => {\n if (calleeNode?.['type'] === 'Identifier') return calleeNode;\n\n if (calleeNode?.['type'] !== 'MemberExpression' || calleeNode['computed']) {\n return null;\n }\n\n const objectNode = calleeNode['object'] as OxcNode | undefined;\n const propertyNode = calleeNode['property'] as OxcNode | undefined;\n\n return objectNode?.['type'] === 'Identifier' &&\n TRANSLATOR_METHOD_NAMES.has(propertyNode?.['name'] as string)\n ? objectNode\n : null;\n};\n\n/**\n * ngx-translate template forms, which live in HTML (component templates or\n * inline `template:` strings) and never reach the JS AST:\n * - `{{ 'home.title' | translate }}` pipe\n * - `[translate]=\"'home.title'\"` bound directive\n * - `translate=\"home.title\"` static directive\n * - `<h2 translate>home.title</h2>` directive keyed by the element text\n */\nconst TRANSLATE_PIPE_PATTERN =\n /(['\"])([^'\"\\r\\n{}|]+)\\1\\s*\\|\\s*translate\\b|\\[translate\\]\\s*=\\s*\"'([^'\"\\r\\n]+)'\"|\\stranslate\\s*=\\s*\"([^'\"\\r\\n{}]+)\"|<[\\w-]+(?:\\s[^<>]*)?\\stranslate(?=[\\s/>])[^<>]*>\\s*([^\\s<>{}]+)\\s*</g;\n\nconst collectTranslatePipeUsages = (text: string): MessageUsage[] => {\n if (!text.includes('translate')) return [];\n\n const usages: MessageUsage[] = [];\n\n for (const match of text.matchAll(TRANSLATE_PIPE_PATTERN)) {\n const elementTextKey = match[5];\n const split = splitMessageIdAtFirstSegment(\n match[2] ?? match[3] ?? match[4] ?? elementTextKey ?? ''\n );\n\n if (!split) continue;\n\n // Element-text form: span the key only, not the whole opening tag.\n const start = elementTextKey\n ? match.index + match[0].lastIndexOf(elementTextKey)\n : match.index;\n\n usages.push({\n ...split,\n start,\n end: elementTextKey\n ? start + elementTextKey.length\n : match.index + match[0].length,\n kind: 'call',\n callerName: 'translate',\n library: '@ngx-translate/core',\n });\n }\n\n return usages;\n};\n\n/**\n * Record `t('path.to.field')` calls on translator bindings, and self-caller\n * calls (`formatMessage({ id })`, `i18n._('id')`).\n */\nconst collectCallUsages = (state: AnalyzerState, program: OxcNode): void => {\n walkAst(program, (node) => {\n if (node['type'] === 'TaggedTemplateExpression') {\n collectTaggedTemplateUsage(state, node);\n return;\n }\n\n if (node['type'] !== 'CallExpression') return;\n\n const callee = node['callee'] as OxcNode | undefined;\n\n // Translator binding call: t('path.to.field'), or one of its methods\n // (next-intl `t.rich('path')`, `t.markup`, `t.raw`, `t.has`).\n const translatorNode = getTranslatorCalleeIdentifier(callee);\n\n if (translatorNode) {\n const binding = resolveBinding(\n state.translatorBindings,\n translatorNode['name'] as string,\n nodeStart(node)\n );\n\n if (binding) {\n const argumentsList = node['arguments'] as OxcNode[] | undefined;\n const messageId = getStaticStringValue(argumentsList?.[0]);\n\n if (messageId) {\n const { namespaceOverride, messagePath } =\n splitNamespacePrefixedId(messageId);\n let dictionaryKey = namespaceOverride ?? binding.dictionaryKey;\n let fieldPath = namespaceOverride\n ? messagePath.split('.')\n : [...binding.keyPrefix, ...messagePath.split('.')];\n\n // Root-scope translator (`useTranslations()`): the first id\n // segment is the dictionary key.\n if (dictionaryKey === null) {\n const split = splitMessageIdAtFirstSegment(\n [...binding.keyPrefix, messagePath].join('.')\n );\n dictionaryKey = split?.dictionaryKey ?? null;\n fieldPath = split?.fieldPath ?? [];\n }\n\n if (dictionaryKey) {\n state.usages.push({\n dictionaryKey,\n fieldPath,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'call',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n moduleSource: binding.moduleSource,\n });\n }\n }\n return;\n }\n }\n\n // Self caller: the call itself carries the message id.\n const descriptor = matchDescriptorForCallee(\n state,\n callee,\n (candidate) => candidate.translationFunction === 'self'\n );\n\n if (!descriptor) return;\n\n const messageId = getSelfCallMessageId(node);\n\n if (!messageId) return;\n\n const fixedDictionaryKey = readValueSources(\n node,\n descriptor.namespaceSources\n );\n const resolved = resolveMessageId(\n descriptor,\n fixedDictionaryKey,\n messageId\n );\n\n if (!resolved) return;\n\n state.usages.push({\n ...resolved,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'call',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n });\n};\n\n/**\n * Lingui macro tagged template: ``t`Hello ${name}` `` — the catalog id is the\n * template text with `{placeholder}` slots for each expression.\n */\nconst collectTaggedTemplateUsage = (\n state: AnalyzerState,\n node: OxcNode\n): void => {\n const descriptor = matchDescriptorForCallee(\n state,\n node['tag'] as OxcNode | undefined,\n (candidate) => candidate.matchAsTaggedTemplate === true\n );\n\n if (!descriptor) return;\n\n const quasiNode = node['quasi'] as OxcNode | undefined;\n const quasis = (quasiNode?.['quasis'] as OxcNode[]) ?? [];\n const expressions = (quasiNode?.['expressions'] as OxcNode[]) ?? [];\n\n let messageId = '';\n\n for (let index = 0; index < quasis.length; index++) {\n const valueNode = quasis[index]?.['value'] as OxcNode | undefined;\n messageId +=\n (valueNode?.['cooked'] as string) ?? (valueNode?.['raw'] as string) ?? '';\n\n if (index < expressions.length) {\n const expression = expressions[index]!;\n const placeholder =\n expression['type'] === 'Identifier'\n ? (expression['name'] as string)\n : String(index);\n messageId += `{${placeholder}}`;\n }\n }\n\n if (!messageId) return;\n\n const fixedDictionaryKey = readValueSources(\n node,\n descriptor.namespaceSources\n );\n const resolved = resolveMessageId(descriptor, fixedDictionaryKey, messageId);\n\n if (!resolved) return;\n\n state.usages.push({\n ...resolved,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'tagged-template',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n};\n\n/** Read a static string JSX attribute from an opening element. */\nconst getJsxAttributeString = (\n openingElement: OxcNode,\n attributeName: string\n): string | null => {\n for (const attribute of (openingElement['attributes'] as OxcNode[]) ?? []) {\n if (attribute['type'] !== 'JSXAttribute') continue;\n\n const nameNode = attribute['name'] as OxcNode | undefined;\n\n if ((nameNode?.['name'] as string) !== attributeName) continue;\n\n const valueNode = attribute['value'] as OxcNode | undefined;\n\n if (!valueNode) return null;\n\n // <Trans i18nKey=\"key\" /> or <Trans i18nKey={'key'} />\n const directValue = getStaticStringValue(valueNode);\n\n if (directValue !== null) return directValue;\n\n if (valueNode['type'] === 'JSXExpressionContainer') {\n return getStaticStringValue(\n valueNode['expression'] as OxcNode | undefined\n );\n }\n\n return null;\n }\n\n return null;\n};\n\n/**\n * Record JSX message components: `<FormattedMessage id=\"home.title\" />`,\n * `<Trans i18nKey=\"richText\" />`, `<Trans id=\"…\" />`.\n */\nconst collectJsxUsages = (state: AnalyzerState, program: OxcNode): void => {\n // Fallback namespace for JSX components without an explicit one: the single\n // distinct translator namespace declared in the file (react-i18next Trans).\n const translatorNamespaces = new Set(\n [...state.translatorBindings.values()]\n .flat()\n .map((binding) => binding.dictionaryKey)\n .filter(\n (dictionaryKey): dictionaryKey is string => dictionaryKey !== null\n )\n );\n const fallbackNamespace =\n translatorNamespaces.size === 1 ? [...translatorNamespaces][0]! : null;\n\n walkAst(program, (node) => {\n if (node['type'] !== 'JSXOpeningElement') return;\n\n const nameNode = node['name'] as OxcNode | undefined;\n\n if (nameNode?.['type'] !== 'JSXIdentifier') return;\n\n const elementName = nameNode['name'] as string;\n\n for (const descriptor of state.activeDescriptors) {\n if (!descriptor.jsxIdAttribute) continue;\n\n if (descriptor.callerName !== elementName) continue;\n\n const messageId = getJsxAttributeString(node, descriptor.jsxIdAttribute);\n\n if (messageId === null) continue;\n\n const namespaceFromAttribute = descriptor.jsxNamespaceAttribute\n ? getJsxAttributeString(node, descriptor.jsxNamespaceAttribute)\n : null;\n const fixedNamespace = descriptor.namespaceSources.find(\n (source) => source.from === 'fixed'\n );\n const dictionaryKey =\n namespaceFromAttribute ??\n (fixedNamespace?.from === 'fixed' ? fixedNamespace.value : null) ??\n fallbackNamespace;\n\n let resolved: { dictionaryKey: string; fieldPath: string[] } | null;\n\n if (dictionaryKey) {\n resolved = {\n dictionaryKey,\n fieldPath: descriptor.flatKey ? [messageId] : messageId.split('.'),\n };\n } else {\n // No namespace anywhere (`<Trans i18nKey=\"home.title\" />` under a\n // root-scope `useTranslation()`): the first id segment names the\n // dictionary, as for root-scope `t()` calls.\n resolved =\n resolveMessageId(descriptor, null, messageId) ??\n splitMessageIdAtFirstSegment(messageId);\n }\n\n if (!resolved) continue;\n\n state.usages.push({\n ...resolved,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'jsx',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n return;\n }\n });\n};\n\n/** Identifier positions that are declarations, not references. */\nconst isDeclarationPosition = (\n identifierNode: OxcNode,\n parentMap: Map<OxcNode, OxcNode>\n): boolean => {\n const parent = parentMap.get(identifierNode);\n\n if (!parent) return false;\n\n const parentType = parent['type'] as string;\n\n if (parentType === 'VariableDeclarator' && parent['id'] === identifierNode) {\n return true;\n }\n\n if (\n (parentType === 'Property' || parentType === 'ObjectProperty') &&\n parentMap.get(parent)?.['type'] === 'ObjectPattern'\n ) {\n return true;\n }\n\n if (parentType === 'ImportSpecifier' || parentType === 'PropertyDefinition') {\n return true;\n }\n\n if (\n parentType === 'FunctionDeclaration' ||\n parentType === 'FunctionExpression' ||\n parentType === 'ArrowFunctionExpression'\n ) {\n return true;\n }\n\n // Object-literal keys: { title: … }\n if (\n (parentType === 'Property' || parentType === 'ObjectProperty') &&\n parent['key'] === identifierNode &&\n parentMap.get(parent)?.['type'] === 'ObjectExpression'\n ) {\n return true;\n }\n\n return false;\n};\n\n/** Identifier used as the (non-computed) property name of a member access. */\nconst isPropertyNamePosition = (\n identifierNode: OxcNode,\n parentMap: Map<OxcNode, OxcNode>\n): boolean => {\n const parent = parentMap.get(identifierNode);\n\n if (!parent) return false;\n\n const parentType = parent['type'] as string;\n\n return (\n (parentType === 'MemberExpression' &&\n parent['property'] === identifierNode &&\n parent['computed'] !== true) ||\n (parentType === 'JSXMemberExpression' &&\n parent['property'] === identifierNode)\n );\n};\n\n/**\n * Record member-access / bare-reference usages of content bindings:\n * `content.section.title`, `{title}` (destructured field reference),\n * Svelte's `$content.title`, Vue's `content.value.title`.\n */\nconst collectMemberUsages = (\n state: AnalyzerState,\n program: OxcNode,\n parentMap: Map<OxcNode, OxcNode>\n): void => {\n if (state.contentBindings.size === 0) return;\n\n walkAst(program, (node) => {\n const nodeType = node['type'] as string;\n\n if (nodeType !== 'Identifier' && nodeType !== 'JSXIdentifier') return;\n\n const rawName = node['name'] as string;\n // Svelte store sugar: `$content` reads the `content` store.\n const variableName = rawName.startsWith('$') ? rawName.slice(1) : rawName;\n const binding = resolveBinding(\n state.contentBindings,\n variableName,\n nodeStart(node)\n );\n\n if (!binding) return;\n\n // Skip identifiers in non-value positions: TypeScript type annotations\n // (`useIntlayer<{ greet: string }>`) and JSX attribute names.\n const parentType = parentMap.get(node)?.['type'] as string | undefined;\n\n if (parentType?.startsWith('TS') || parentType === 'JSXAttribute') return;\n\n if (isDeclarationPosition(node, parentMap)) return;\n\n if (isPropertyNamePosition(node, parentMap)) return;\n\n // Climb the member chain upward, collecting property segments.\n const fieldPath = [...binding.basePath];\n const fieldSpans: { start: number; end: number }[] = fieldPath.map(() => ({\n start: nodeStart(node),\n end: nodeEnd(node),\n }));\n\n let currentNode: OxcNode = node;\n\n while (true) {\n const parent = parentMap.get(currentNode);\n\n if (!parent) break;\n\n const parentType = parent['type'] as string;\n const isMemberAccess =\n (parentType === 'MemberExpression' &&\n parent['object'] === currentNode &&\n parent['computed'] !== true) ||\n (parentType === 'JSXMemberExpression' &&\n parent['object'] === currentNode);\n\n if (isMemberAccess) {\n const propertyNode = parent['property'] as OxcNode;\n const propertyName = propertyNode['name'] as string;\n\n if (!ACCESSOR_PROPERTY_NAMES.has(propertyName)) {\n fieldPath.push(propertyName);\n fieldSpans.push({\n start: nodeStart(propertyNode),\n end: nodeEnd(propertyNode),\n });\n }\n currentNode = parent;\n continue;\n }\n\n // Computed string access: content['title']\n if (\n parentType === 'MemberExpression' &&\n parent['object'] === currentNode &&\n parent['computed'] === true\n ) {\n const propertyValue = getStaticStringValue(\n parent['property'] as OxcNode | undefined\n );\n\n if (propertyValue === null) break;\n\n fieldPath.push(propertyValue);\n fieldSpans.push({\n start: nodeStart(parent['property'] as OxcNode),\n end: nodeEnd(parent['property'] as OxcNode),\n });\n currentNode = parent;\n continue;\n }\n\n // Call of an accessor / chain terminator: content.title.use()\n if (parentType === 'CallExpression' && parent['callee'] === currentNode) {\n currentNode = parent;\n continue;\n }\n\n break;\n }\n\n state.usages.push({\n dictionaryKey: binding.dictionaryKey,\n fieldPath,\n fieldSpans,\n start: nodeStart(node),\n end: nodeEnd(currentNode),\n kind: 'member',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n moduleSource: binding.moduleSource,\n // No explicit property segment: the usage only names the variable.\n isBareReference: fieldPath.length === binding.basePath.length,\n });\n return true;\n });\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Analyse a source file and return every resolvable translation usage:\n * base-intlayer content access and all compat-library forms (translation\n * functions, self calls, JSX message components, tagged templates).\n *\n * Pure and self-contained (oxc parse only) — shared by the LSP handlers and\n * the VS Code extension providers/decorations.\n *\n * @param text - Full source text (a script: TS/TSX or an extracted SFC block).\n * @returns Usages ordered by start offset.\n */\nexport const collectMessageUsages = (text: string): MessageUsage[] => {\n const pipeUsages = collectTranslatePipeUsages(text);\n const program = parseText(text);\n\n if (!program) return pipeUsages;\n\n const fileImportSources = collectImportSources(program);\n const parentMap = buildParentMap(program);\n const state: AnalyzerState = {\n usages: [],\n translatorBindings: new Map(),\n contentBindings: new Map(),\n activeDescriptors: ANALYZED_CALLERS.filter((descriptor) =>\n isCallerActive(descriptor, fileImportSources)\n ),\n importedLocalNames: collectImportedLocalNames(program),\n parentMap,\n program,\n };\n\n collectBindings(state, program);\n collectCallUsages(state, program);\n collectJsxUsages(state, program);\n collectMemberUsages(state, program, parentMap);\n\n return [...state.usages, ...pipeUsages].sort(\n (first, second) => first.start - second.start\n );\n};\n\n/**\n * Resolve the dictionary key declared by a single call-expression node when\n * it matches any registered non-self caller (`useIntlayer(\"key\")`,\n * `useI18n({ namespace })`, …). Used for on-the-fly checks where the full\n * file analysis is not needed (e.g. completion context).\n *\n * @param callNode - A candidate CallExpression node.\n */\nexport const matchCallNamespace = (callNode: OxcNode): string | null => {\n if (callNode['type'] !== 'CallExpression') return null;\n\n const callee = getCalleeName(callNode['callee'] as OxcNode | undefined);\n\n if (!callee) return null;\n\n for (const descriptor of ALL_CALLERS) {\n if (descriptor.translationFunction === 'self') continue;\n\n if (descriptor.callerName !== callee.name) continue;\n\n if (callee.isMethod && !descriptor.matchAsMethod) continue;\n\n const namespaceValue = readValueSources(\n callNode,\n descriptor.namespaceSources\n );\n\n if (namespaceValue !== null) {\n return splitNestedNamespace(descriptor, namespaceValue).dictionaryKey;\n }\n }\n\n return null;\n};\n\n/**\n * A call site declaring which dictionary a caller reads\n * (`useIntlayer(\"home\")`, `useI18n({ namespace: 'home' })`), with the spans\n * needed to anchor diagnostics and cursor checks.\n */\nexport type NamespaceReference = {\n dictionaryKey: string;\n callerName: string;\n library: string;\n /** Span of the whole call expression. */\n callStart: number;\n callEnd: number;\n /** Span of the matched callee name (identifier or method property). */\n calleeStart: number;\n calleeEnd: number;\n /** Span of the namespace argument (string literal or option value). */\n namespaceStart: number;\n namespaceEnd: number;\n};\n\n/**\n * The AST node holding the namespace string for a given value source, when\n * that source is addressable in the call (positional argument or options\n * property).\n */\nconst getNamespaceArgumentNode = (\n callNode: OxcNode,\n source: CallerValueSource\n): OxcNode | null => {\n const argumentsList = callNode['arguments'] as OxcNode[] | undefined;\n\n if (source.from === 'argument') {\n return argumentsList?.[source.index] ?? null;\n }\n\n if (source.from === 'option') {\n const property = getObjectPropertyNode(\n argumentsList?.[source.argumentIndex],\n source.property\n );\n\n return (property?.['value'] as OxcNode | undefined) ?? null;\n }\n\n return null;\n};\n\n/**\n * Collect every call site with an addressable namespace argument (positional\n * or options property) resolving to a static string. Powers the\n * unknown-dictionary diagnostics and `findKeyAtOffset`.\n *\n * Self callers (`formatMessage`, lingui `t`/`_`) don't declare a namespace at\n * the call site and are excluded.\n *\n * @param text - Full source text.\n */\nexport const collectNamespaceReferences = (\n text: string\n): NamespaceReference[] => {\n const program = parseText(text);\n\n if (!program) return [];\n\n const fileImportSources = collectImportSources(program);\n const activeDescriptors = ANALYZED_CALLERS.filter(\n (descriptor) =>\n descriptor.translationFunction !== 'self' &&\n isCallerActive(descriptor, fileImportSources)\n );\n const references: NamespaceReference[] = [];\n\n walkAst(program, (node) => {\n if (node['type'] !== 'CallExpression') return;\n\n const calleeNode = node['callee'] as OxcNode | undefined;\n const callee = getCalleeName(calleeNode);\n\n if (!callee) return;\n\n for (const descriptor of activeDescriptors) {\n if (descriptor.callerName !== callee.name) continue;\n\n if (callee.isMethod && !descriptor.matchAsMethod) continue;\n\n const calleeNameNode =\n callee.isMethod && calleeNode\n ? (calleeNode['property'] as OxcNode)\n : calleeNode!;\n\n for (const source of descriptor.namespaceSources) {\n const namespaceNode = getNamespaceArgumentNode(node, source);\n const namespaceValue = getStaticStringValue(namespaceNode ?? undefined);\n\n if (!namespaceNode || namespaceValue === null) continue;\n\n references.push({\n dictionaryKey: splitNestedNamespace(descriptor, namespaceValue)\n .dictionaryKey,\n callerName: descriptor.callerName,\n library: descriptor.library,\n callStart: nodeStart(node),\n callEnd: nodeEnd(node),\n calleeStart: nodeStart(calleeNameNode),\n calleeEnd: nodeEnd(calleeNameNode),\n namespaceStart: nodeStart(namespaceNode),\n namespaceEnd: nodeEnd(namespaceNode),\n });\n return;\n }\n }\n });\n\n return references;\n};\n\n/**\n * A source variable bound to a dictionary by a caller declaration:\n * dictionary content (or a field subtree of it) for `content` callers, or a\n * translation function for `return-value` / `destructured-t` callers.\n */\nexport type CallerVariableBinding = {\n /** Local variable name. */\n variableName: string;\n /** The dictionary the variable reads from. */\n dictionaryKey: string;\n /**\n * Field path from the dictionary root the variable points at (content\n * bindings), or the key prefix applied to every call (translator bindings).\n */\n basePath: string[];\n /** Whether the variable holds content or a translation function. */\n bindingKind: 'content' | 'translator';\n /** The caller that created the binding. */\n callerName: string;\n library: string;\n};\n\n/**\n * Collect every variable bound to a dictionary in the file. Used by consumers\n * that scan non-script regions (Vue/Angular templates) for references to\n * those variables, or that need to know which dictionaries a file consumes.\n *\n * @param text - Full source text (a script: TS/TSX or an extracted SFC block).\n */\nexport const collectCallerBindings = (\n text: string\n): CallerVariableBinding[] => {\n const program = parseText(text);\n\n if (!program) return [];\n\n const fileImportSources = collectImportSources(program);\n const state: AnalyzerState = {\n usages: [],\n translatorBindings: new Map(),\n contentBindings: new Map(),\n activeDescriptors: ANALYZED_CALLERS.filter((descriptor) =>\n isCallerActive(descriptor, fileImportSources)\n ),\n importedLocalNames: collectImportedLocalNames(program),\n parentMap: buildParentMap(program),\n program,\n };\n\n collectBindings(state, program);\n\n return [\n ...[...state.contentBindings.entries()].flatMap(\n ([variableName, bindings]) =>\n bindings.map(\n (binding): CallerVariableBinding => ({\n variableName,\n dictionaryKey: binding.dictionaryKey,\n basePath: binding.basePath,\n bindingKind: 'content',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n })\n )\n ),\n ...[...state.translatorBindings.entries()].flatMap(\n ([variableName, bindings]) =>\n bindings\n // Root-scope translators have no bound dictionary to expose.\n .filter((binding) => binding.dictionaryKey !== null)\n .map(\n (binding): CallerVariableBinding => ({\n variableName,\n dictionaryKey: binding.dictionaryKey!,\n basePath: binding.keyPrefix,\n bindingKind: 'translator',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n })\n )\n ),\n ];\n};\n\n/**\n * Find the most specific translation usage at `offset`.\n *\n * For member chains the field path is trimmed to the segment under the\n * cursor: hovering `section` in `content.section.title` yields\n * `['section']`, not the full chain.\n *\n * Dictionary-level `namespace` usages are only returned when no field-level\n * usage matches the offset.\n *\n * @param text - Full source text.\n * @param offset - Cursor offset in `text`.\n */\nexport const findMessageUsageAtOffset = (\n text: string,\n offset: number\n): MessageUsage | null => {\n const usages = collectMessageUsages(text);\n\n let bestMatch: MessageUsage | null = null;\n\n for (const usage of usages) {\n if (offset < usage.start || offset > usage.end) continue;\n\n const isBetter =\n !bestMatch ||\n // Prefer field-level usages over dictionary-level ones…\n (bestMatch.kind === 'namespace' && usage.kind !== 'namespace') ||\n // …then the smallest span containing the offset.\n (usage.end - usage.start < bestMatch.end - bestMatch.start &&\n !(bestMatch.kind !== 'namespace' && usage.kind === 'namespace'));\n\n if (isBetter) bestMatch = usage;\n }\n\n if (!bestMatch) return null;\n\n // Trim member chains to the segment under the cursor.\n if (bestMatch.kind === 'member' && bestMatch.fieldSpans) {\n let lastIncludedIndex = -1;\n\n for (let index = 0; index < bestMatch.fieldSpans.length; index++) {\n if (offset >= bestMatch.fieldSpans[index]!.start) {\n lastIncludedIndex = index;\n }\n }\n\n return {\n ...bestMatch,\n fieldPath: bestMatch.fieldPath.slice(0, lastIncludedIndex + 1),\n fieldSpans: bestMatch.fieldSpans.slice(0, lastIncludedIndex + 1),\n };\n }\n\n return bestMatch;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"usageAnalyzer.mjs","names":["ALL_CALLERS","isCallerActive"],"sources":["../../src/usageAnalyzer.ts"],"sourcesContent":["import {\n ALL_CALLERS,\n type CallerDescriptor,\n type CallerValueSource,\n isCallerActive,\n} from './callers';\nimport { EDITOR_CALLERS } from './callers/editorCallers';\nimport {\n buildParentMap,\n getObjectPropertyNode,\n getObjectPropertyString,\n getPropertyKeyName,\n getStaticStringValue,\n nodeEnd,\n nodeStart,\n type OxcNode,\n parseText,\n walkAst,\n} from './oxcUtils';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** How a message usage appears in source code. */\nexport type MessageUsageKind =\n /** Translation-function or self call: `t('title')`, `formatMessage({ id })`. */\n | 'call'\n /** Member access / bare reference on a content object: `content.title`. */\n | 'member'\n /** Destructured content field: `const { title } = useIntlayer('home')`. */\n | 'destructure'\n /** JSX message component: `<FormattedMessage id=\"home.title\" />`. */\n | 'jsx'\n /** Tagged template: lingui's ``t`Hello` ``. */\n | 'tagged-template'\n /** The caller call itself (dictionary-level usage): `useIntlayer('home')`. */\n | 'namespace';\n\n/**\n * One resolved translation usage inside a source file: which dictionary and\n * field it reads, and the text span it occupies.\n */\nexport type MessageUsage = {\n /** The intlayer dictionary key the usage reads from. */\n dictionaryKey: string;\n /**\n * Path of content fields from the dictionary root. Empty for\n * dictionary-level usages (`namespace` kind, or a bare content variable).\n */\n fieldPath: string[];\n /**\n * Spans of each `fieldPath` segment, aligned by index, when the segments\n * are addressable in source (member chains). Used to trim the path to the\n * segment under the cursor.\n */\n fieldSpans?: { start: number; end: number }[];\n /** Start offset of the usage expression. */\n start: number;\n /** End offset of the usage expression. */\n end: number;\n kind: MessageUsageKind;\n /** The caller that produced the usage, e.g. `'useTranslations'`. */\n callerName: string;\n /** The library the caller belongs to, e.g. `'next-intl'` or `'intlayer'`. */\n library: string;\n /** Module specifier the caller was imported from, when resolvable. */\n moduleSource?: string;\n /**\n * `true` for `member` usages that are a bare reference to a bound variable\n * (`{greet}` in JSX after `const { greet } = useIntlayer(…)`) — the field\n * name itself is not spelled at the usage site. Excluded from\n * find-references results but kept for decorations and hover.\n */\n isBareReference?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Internal binding models\n// ---------------------------------------------------------------------------\n\n/**\n * Variable holding a translation function (`t`) with a bound namespace.\n * `dictionaryKey` is `null` for root-scope translators (`useTranslations()`\n * without a namespace) — the dictionary is then the first dot-segment of\n * each message id.\n */\ntype TranslatorBinding = BindingScope & {\n dictionaryKey: string | null;\n keyPrefix: string[];\n descriptor: CallerDescriptor;\n moduleSource?: string;\n};\n\n/** Variable holding dictionary content (or a field subtree of it). */\ntype ContentBinding = BindingScope & {\n dictionaryKey: string;\n basePath: string[];\n descriptor: CallerDescriptor;\n moduleSource?: string;\n};\n\n/**\n * Where a binding is visible. Two components in the same file routinely bind\n * the same variable name to different dictionaries:\n *\n * const Page = () => { const content = useIntlayer('benchmark'); … }\n * const App = () => { const content = useIntlayer('app'); … }\n *\n * Without a scope, the second declaration would shadow the first and every\n * usage in the file would resolve to the last dictionary declared.\n */\ntype BindingScope = {\n /** Span of the function (or the program) the declaration lives in. */\n scopeStart: number;\n scopeEnd: number;\n /** End offset of the declaration itself — usages before it are not bound. */\n declarationEnd: number;\n};\n\n/**\n * Property names that are framework accessors rather than content fields\n * (react `.value`, vue refs `.value`, editor `.raw`/`.use`): they are skipped\n * when building field paths.\n */\nconst ACCESSOR_PROPERTY_NAMES = new Set(['value', 'raw', 'use']);\n\n/** The shared registry plus the callers only the editor tooling resolves. */\nconst ANALYZED_CALLERS: CallerDescriptor[] = [\n ...ALL_CALLERS,\n ...EDITOR_CALLERS,\n];\n\n// ---------------------------------------------------------------------------\n// Match helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a value source against a call expression's arguments.\n */\nconst readValueSource = (\n callNode: OxcNode,\n source: CallerValueSource\n): string | null => {\n const argumentsList = callNode['arguments'] as OxcNode[] | undefined;\n\n switch (source.from) {\n case 'argument':\n return getStaticStringValue(argumentsList?.[source.index]);\n case 'option':\n return getObjectPropertyString(\n argumentsList?.[source.argumentIndex],\n source.property\n );\n case 'fixed':\n return source.value;\n case 'path-first-segment':\n // Resolved from the message id at usage time, not from the call shape.\n return null;\n }\n};\n\n/** Read the first matching value from a list of sources. */\nconst readValueSources = (\n callNode: OxcNode,\n sources: CallerValueSource[] | undefined\n): string | null => {\n for (const source of sources ?? []) {\n const value = readValueSource(callNode, source);\n\n if (value !== null) return value;\n }\n\n return null;\n};\n\n/**\n * Apply nested-namespace semantics: for descriptors flagged\n * `nestedNamespace`, a dotted namespace is split at the first `.` into the\n * dictionary key and a key-prefix path (next-intl:\n * `useTranslations('about.counter')` → dictionary `about`, prefix\n * `['counter']`).\n */\nconst splitNestedNamespace = (\n descriptor: CallerDescriptor,\n rawNamespace: string\n): { dictionaryKey: string; prefixPath: string[] } => {\n if (!descriptor.nestedNamespace || !rawNamespace.includes('.')) {\n return { dictionaryKey: rawNamespace, prefixPath: [] };\n }\n\n const segments = rawNamespace.split('.');\n\n return { dictionaryKey: segments[0]!, prefixPath: segments.slice(1) };\n};\n\n/**\n * Return the caller name matched by a call/tagged-template callee: the bare\n * identifier name, or the property name of a member expression when the\n * descriptor allows method matching.\n */\nconst getCalleeName = (\n calleeNode: OxcNode | undefined\n): { name: string; isMethod: boolean } | null => {\n if (!calleeNode) return null;\n\n if (calleeNode['type'] === 'Identifier') {\n return { name: calleeNode['name'] as string, isMethod: false };\n }\n\n if (\n calleeNode['type'] === 'MemberExpression' &&\n calleeNode['computed'] !== true\n ) {\n const propertyNode = calleeNode['property'] as OxcNode | undefined;\n\n if (propertyNode?.['type'] === 'Identifier') {\n return { name: propertyNode['name'] as string, isMethod: true };\n }\n }\n\n return null;\n};\n\n/**\n * The message id of a self caller: either the first string argument or the\n * `id` property of a descriptor-object first argument\n * (`formatMessage({ id: 'home.title' })`, `i18n._({ id: '…' })`).\n */\nconst getSelfCallMessageId = (callNode: OxcNode): string | null => {\n const argumentsList = callNode['arguments'] as OxcNode[] | undefined;\n const firstArgument = argumentsList?.[0];\n\n if (!firstArgument) return null;\n\n return (\n getStaticStringValue(firstArgument) ??\n getObjectPropertyString(firstArgument, 'id')\n );\n};\n\n/**\n * Split a message id into dictionary key + field path according to the\n * descriptor semantics.\n */\nconst resolveMessageId = (\n descriptor: CallerDescriptor,\n fixedDictionaryKey: string | null,\n messageId: string\n): { dictionaryKey: string; fieldPath: string[] } | null => {\n if (fixedDictionaryKey !== null) {\n return {\n dictionaryKey: fixedDictionaryKey,\n fieldPath: descriptor.flatKey ? [messageId] : messageId.split('.'),\n };\n }\n\n const usesPathFirstSegment = descriptor.namespaceSources.some(\n (source) => source.from === 'path-first-segment'\n );\n\n if (!usesPathFirstSegment) return null;\n\n const segments = messageId.split('.');\n\n if (!segments[0]) return null;\n\n // A single-segment id names no dictionary: it lives in the library's\n // whole-file catalog (lingui's `messages`), id kept intact.\n if (segments.length === 1) {\n const rootDictionaryKey = getLibraryRootDictionaryKey(descriptor.library);\n\n return rootDictionaryKey\n ? { dictionaryKey: rootDictionaryKey, fieldPath: [messageId] }\n : { dictionaryKey: segments[0], fieldPath: [] };\n }\n\n return { dictionaryKey: segments[0], fieldPath: segments.slice(1) };\n};\n\n/**\n * Split a namespace-less message id at its first dot: the first segment is the\n * dictionary key, the rest the field path (`'home.hero.title'` → `home`,\n * `['hero', 'title']`).\n */\nconst splitMessageIdAtFirstSegment = (\n messageId: string\n): { dictionaryKey: string; fieldPath: string[] } | null => {\n const [dictionaryKey, ...fieldPath] = messageId.split('.');\n\n return dictionaryKey ? { dictionaryKey, fieldPath } : null;\n};\n\n/**\n * The whole-file catalog a library falls back to when an id-derived key names\n * no dictionary, declared on any of its callers (`useLingui` → `messages`).\n */\nexport const getLibraryRootDictionaryKey = (\n library: CallerDescriptor['library']\n): string | undefined =>\n ALL_CALLERS.find(\n (candidate) =>\n candidate.library === library && candidate.rootDictionaryKey !== undefined\n )?.rootDictionaryKey;\n\n/**\n * i18next-style `ns:key` ids override the bound namespace:\n * `t('about:title')` reads the `about` dictionary even when the translator\n * was created with another namespace.\n */\nconst splitNamespacePrefixedId = (\n messageId: string\n): { namespaceOverride: string | null; messagePath: string } => {\n const separatorIndex = messageId.indexOf(':');\n\n if (separatorIndex <= 0) {\n return { namespaceOverride: null, messagePath: messageId };\n }\n\n return {\n namespaceOverride: messageId.slice(0, separatorIndex),\n messagePath: messageId.slice(separatorIndex + 1),\n };\n};\n\n// ---------------------------------------------------------------------------\n// Analyzer\n// ---------------------------------------------------------------------------\n\n/** Unwrap `await expression` down to the awaited expression. */\nconst unwrapAwait = (node: OxcNode | undefined): OxcNode | undefined =>\n node?.['type'] === 'AwaitExpression'\n ? (node['argument'] as OxcNode | undefined)\n : node;\n\n/** Collect every module specifier imported by the program. */\nconst collectImportSources = (program: OxcNode): Set<string> => {\n const importSources = new Set<string>();\n\n for (const statement of (program['body'] as OxcNode[]) ?? []) {\n if (statement['type'] !== 'ImportDeclaration') continue;\n const sourceValue = (statement['source'] as OxcNode | undefined)?.['value'];\n\n if (typeof sourceValue === 'string') importSources.add(sourceValue);\n }\n\n return importSources;\n};\n\n/** Map each imported local name to its module specifier. */\nconst collectImportedLocalNames = (program: OxcNode): Map<string, string> => {\n const localNameToSource = new Map<string, string>();\n\n for (const statement of (program['body'] as OxcNode[]) ?? []) {\n if (statement['type'] !== 'ImportDeclaration') continue;\n const sourceValue = (statement['source'] as OxcNode | undefined)?.['value'];\n\n if (typeof sourceValue !== 'string') continue;\n\n for (const specifier of (statement['specifiers'] as OxcNode[]) ?? []) {\n const localName = (specifier['local'] as OxcNode | undefined)?.['name'];\n\n if (typeof localName === 'string') {\n localNameToSource.set(localName, sourceValue);\n }\n }\n }\n\n return localNameToSource;\n};\n\ntype AnalyzerState = {\n usages: MessageUsage[];\n /** Bindings are keyed by variable name, then by declaration (see BindingScope). */\n translatorBindings: Map<string, TranslatorBinding[]>;\n contentBindings: Map<string, ContentBinding[]>;\n activeDescriptors: CallerDescriptor[];\n importedLocalNames: Map<string, string>;\n parentMap: Map<OxcNode, OxcNode>;\n program: OxcNode;\n};\n\n/** Node types that open a new binding scope. */\nconst SCOPE_NODE_TYPES = new Set([\n 'FunctionDeclaration',\n 'FunctionExpression',\n 'ArrowFunctionExpression',\n 'ClassMethod',\n 'ObjectMethod',\n 'StaticBlock',\n 'Program',\n]);\n\n/**\n * Span of the nearest enclosing function — the region a declaration is\n * visible in. Falls back to the whole program for module-level declarations.\n */\nconst getEnclosingScope = (\n state: AnalyzerState,\n node: OxcNode\n): { scopeStart: number; scopeEnd: number } => {\n let current: OxcNode | undefined = node;\n\n while (current) {\n if (SCOPE_NODE_TYPES.has(current['type'] as string)) {\n return { scopeStart: nodeStart(current), scopeEnd: nodeEnd(current) };\n }\n current = state.parentMap.get(current);\n }\n\n return {\n scopeStart: nodeStart(state.program),\n scopeEnd: nodeEnd(state.program),\n };\n};\n\nconst addBinding = <T>(\n bindings: Map<string, T[]>,\n variableName: string,\n binding: T\n): void => {\n const existing = bindings.get(variableName);\n\n if (existing) {\n existing.push(binding);\n } else {\n bindings.set(variableName, [binding]);\n }\n};\n\n/**\n * The binding a variable resolves to at `offset`: the innermost scope that\n * contains the offset, among declarations that precede it.\n */\nconst resolveBinding = <T extends BindingScope>(\n bindings: Map<string, T[]>,\n variableName: string,\n offset: number\n): T | undefined => {\n const candidates = bindings.get(variableName);\n\n if (!candidates) return undefined;\n\n let best: T | undefined;\n\n for (const candidate of candidates) {\n if (offset < candidate.scopeStart || offset > candidate.scopeEnd) continue;\n\n // A usage textually before its declaration belongs to an outer binding.\n if (offset < candidate.declarationEnd) continue;\n\n // Innermost scope wins; on equal scopes the latest declaration wins.\n if (\n !best ||\n candidate.scopeStart > best.scopeStart ||\n (candidate.scopeStart === best.scopeStart &&\n candidate.declarationEnd > best.declarationEnd)\n ) {\n best = candidate;\n }\n }\n\n return best;\n};\n\n/**\n * Find the descriptor matching a call (or tagged template) callee among the\n * active descriptors.\n */\nconst matchDescriptorForCallee = (\n state: AnalyzerState,\n calleeNode: OxcNode | undefined,\n filter?: (descriptor: CallerDescriptor) => boolean\n): CallerDescriptor | null => {\n const callee = getCalleeName(calleeNode);\n\n if (!callee) return null;\n\n // An imported store read through `$` takes precedence over a caller that\n // happens to share the prefixed name (svelte-i18n `$t` vs vue-i18n `$t`).\n const storeName = getSvelteStoreName(state, callee);\n const calleeNames = storeName ? [storeName, callee.name] : [callee.name];\n\n for (const calleeName of calleeNames) {\n for (const descriptor of state.activeDescriptors) {\n if (descriptor.callerName !== calleeName) continue;\n\n if (callee.isMethod && !descriptor.matchAsMethod) continue;\n\n if (filter && !filter(descriptor)) continue;\n\n return descriptor;\n }\n }\n\n return null;\n};\n\n/**\n * Svelte auto-subscribes an imported store through a `$` prefix:\n * `import { _ } from 'svelte-i18n'` is read as `$_('home.title')`. Returns the\n * store's imported name for such a callee.\n */\nconst getSvelteStoreName = (\n state: AnalyzerState,\n callee: { name: string; isMethod: boolean }\n): string | null => {\n if (callee.isMethod || !callee.name.startsWith('$')) return null;\n\n const storeName = callee.name.slice(1);\n\n return state.importedLocalNames.has(storeName) ? storeName : null;\n};\n\n/** The module specifier a caller local name was imported from, if any. */\nconst getModuleSource = (\n state: AnalyzerState,\n descriptor: CallerDescriptor\n): string | undefined =>\n state.importedLocalNames.get(descriptor.callerName) ?? undefined;\n\n/**\n * Recursively register a content destructure pattern: each property key is a\n * field usage, each bound identifier becomes a content binding, and nested\n * patterns extend the field path.\n *\n * const { searchInput: { text: alias } } = useIntlayer('key')\n * → usages: ['searchInput'], ['searchInput', 'text']\n * → binding: alias → ['searchInput', 'text']\n */\nconst collectContentDestructure = (\n state: AnalyzerState,\n pattern: OxcNode,\n dictionaryKey: string,\n basePath: string[],\n descriptor: CallerDescriptor,\n moduleSource: string | undefined,\n scope: BindingScope\n): void => {\n for (const property of (pattern['properties'] as OxcNode[]) ?? []) {\n const propertyType = property['type'] as string;\n\n if (propertyType !== 'Property' && propertyType !== 'ObjectProperty') {\n continue;\n }\n\n const keyNode = property['key'] as OxcNode | undefined;\n const fieldName = getPropertyKeyName(keyNode);\n\n if (!keyNode || !fieldName) continue;\n\n const fieldPath = [...basePath, fieldName];\n\n state.usages.push({\n dictionaryKey,\n fieldPath,\n start: nodeStart(keyNode),\n end: nodeEnd(keyNode),\n kind: 'destructure',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource,\n });\n\n // Unwrap default values: { title = fallback }\n let valueNode = property['value'] as OxcNode | undefined;\n\n if (valueNode?.['type'] === 'AssignmentPattern') {\n valueNode = valueNode['left'] as OxcNode | undefined;\n }\n\n if (valueNode?.['type'] === 'Identifier') {\n addBinding(state.contentBindings, valueNode['name'] as string, {\n dictionaryKey,\n basePath: fieldPath,\n descriptor,\n moduleSource,\n ...scope,\n });\n } else if (valueNode?.['type'] === 'ObjectPattern') {\n collectContentDestructure(\n state,\n valueNode,\n dictionaryKey,\n fieldPath,\n descriptor,\n moduleSource,\n scope\n );\n }\n }\n};\n\n/**\n * Register bindings created by `const … = caller(…)` declarations, and record\n * dictionary-level (`namespace`) usages for every matched caller call.\n */\nconst collectBindings = (state: AnalyzerState, program: OxcNode): void => {\n walkAst(program, (node) => {\n if (node['type'] === 'CallExpression') {\n const descriptor = matchDescriptorForCallee(\n state,\n node['callee'] as OxcNode | undefined,\n (candidate) => candidate.translationFunction !== 'self'\n );\n\n if (descriptor) {\n const rawNamespace = readValueSources(\n node,\n descriptor.namespaceSources\n );\n\n if (rawNamespace) {\n const { dictionaryKey } = splitNestedNamespace(\n descriptor,\n rawNamespace\n );\n\n state.usages.push({\n dictionaryKey,\n fieldPath: [],\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'namespace',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n }\n }\n return;\n }\n\n if (node['type'] !== 'VariableDeclarator') return;\n\n const initializer = unwrapAwait(node['init'] as OxcNode | undefined);\n\n if (\n initializer?.['type'] === 'ArrowFunctionExpression' ||\n initializer?.['type'] === 'FunctionExpression'\n ) {\n collectPrefixingWrapperBinding(state, node, initializer);\n return;\n }\n\n if (initializer?.['type'] !== 'CallExpression') return;\n\n const descriptor = matchDescriptorForCallee(\n state,\n initializer['callee'] as OxcNode | undefined,\n (candidate) => candidate.translationFunction !== 'self'\n );\n\n if (!descriptor) return;\n\n const rawNamespace = readValueSources(\n initializer,\n descriptor.namespaceSources\n );\n\n // Root scope: `useTranslations()` — the dictionary comes from each id.\n if (!rawNamespace && !descriptor.allowRootScope) return;\n\n const namespaceSplit = rawNamespace\n ? splitNestedNamespace(descriptor, rawNamespace)\n : { dictionaryKey: null, prefixPath: [] };\n\n const keyPrefixValue = readValueSources(\n initializer,\n descriptor.keyPrefixSources\n );\n const keyPrefix = [\n ...namespaceSplit.prefixPath,\n ...(keyPrefixValue ? keyPrefixValue.split('.') : []),\n ];\n const dictionaryKey = namespaceSplit.dictionaryKey;\n const moduleSource = getModuleSource(state, descriptor);\n const idNode = node['id'] as OxcNode | undefined;\n\n if (!idNode) return;\n\n const scope: BindingScope = {\n ...getEnclosingScope(state, node),\n declarationEnd: nodeEnd(node),\n };\n\n // const t = useTranslations('ns') / const content = useIntlayer('key')\n if (idNode['type'] === 'Identifier') {\n const variableName = idNode['name'] as string;\n\n if (descriptor.translationFunction === 'return-value') {\n addBinding(state.translatorBindings, variableName, {\n dictionaryKey,\n keyPrefix,\n descriptor,\n moduleSource,\n ...scope,\n });\n } else if (\n descriptor.translationFunction === 'content' &&\n dictionaryKey\n ) {\n addBinding(state.contentBindings, variableName, {\n dictionaryKey,\n basePath: keyPrefix,\n descriptor,\n moduleSource,\n ...scope,\n });\n }\n return;\n }\n\n // const { t } = useTranslation('ns') / const { title } = useIntlayer('key')\n if (idNode['type'] !== 'ObjectPattern') return;\n\n if (descriptor.translationFunction === 'content') {\n if (!dictionaryKey) return;\n\n collectContentDestructure(\n state,\n idNode,\n dictionaryKey,\n keyPrefix,\n descriptor,\n moduleSource,\n scope\n );\n return;\n }\n\n if (descriptor.translationFunction !== 'destructured-t') return;\n\n for (const property of (idNode['properties'] as OxcNode[]) ?? []) {\n const propertyType = property['type'] as string;\n\n if (propertyType !== 'Property' && propertyType !== 'ObjectProperty') {\n continue;\n }\n\n const keyNode = property['key'] as OxcNode | undefined;\n const valueNode = property['value'] as OxcNode | undefined;\n const fieldName = getPropertyKeyName(keyNode);\n const localName =\n valueNode?.['type'] === 'Identifier'\n ? (valueNode['name'] as string)\n : null;\n\n // Only the `t` property carries the translation function.\n if (fieldName !== 't' || !localName) continue;\n\n addBinding(state.translatorBindings, localName, {\n dictionaryKey,\n keyPrefix,\n descriptor,\n moduleSource,\n ...scope,\n });\n }\n });\n};\n\n/** The single returned expression of a function body, if any. */\nconst getReturnedExpression = (functionNode: OxcNode): OxcNode | undefined => {\n const body = functionNode['body'] as OxcNode | undefined;\n\n if (body?.['type'] !== 'BlockStatement') return body;\n\n const statements = (body['body'] as OxcNode[] | undefined) ?? [];\n const onlyStatement = statements.length === 1 ? statements[0] : undefined;\n\n return onlyStatement?.['type'] === 'ReturnStatement'\n ? (onlyStatement['argument'] as OxcNode | undefined)\n : undefined;\n};\n\n/**\n * The static prefix of a `` `footer.${id}` `` template whose only\n * substitution is `parameterName`, split into path segments.\n */\nconst getTemplatePrefixSegments = (\n templateNode: OxcNode | undefined,\n parameterName: string\n): string[] | null => {\n if (templateNode?.['type'] !== 'TemplateLiteral') return null;\n\n const quasis = (templateNode['quasis'] as OxcNode[] | undefined) ?? [];\n const expressions =\n (templateNode['expressions'] as OxcNode[] | undefined) ?? [];\n const readQuasi = (quasi: OxcNode | undefined): string | undefined => {\n const value = quasi?.['value'] as OxcNode | undefined;\n\n return (value?.['cooked'] as string | undefined) ?? undefined;\n };\n\n if (\n expressions.length !== 1 ||\n expressions[0]?.['type'] !== 'Identifier' ||\n expressions[0]['name'] !== parameterName ||\n readQuasi(quasis[1]) !== ''\n ) {\n return null;\n }\n\n const prefix = readQuasi(quasis[0]);\n\n if (!prefix?.endsWith('.')) return null;\n\n return prefix.slice(0, -1).split('.');\n};\n\n/**\n * Register a local wrapper that prefixes every id before translating it as a\n * translator binding:\n *\n * const t = (id: string) => i18n._(`footer.${id}`); t('github')\n * const tf = (key) => t(`form.${key}`); tf('name')\n */\nconst collectPrefixingWrapperBinding = (\n state: AnalyzerState,\n declaratorNode: OxcNode,\n functionNode: OxcNode\n): void => {\n const idNode = declaratorNode['id'] as OxcNode | undefined;\n const parameterNode = (functionNode['params'] as OxcNode[] | undefined)?.[0];\n const callNode = getReturnedExpression(functionNode);\n\n if (\n idNode?.['type'] !== 'Identifier' ||\n parameterNode?.['type'] !== 'Identifier' ||\n callNode?.['type'] !== 'CallExpression'\n ) {\n return;\n }\n\n const prefixSegments = getTemplatePrefixSegments(\n (callNode['arguments'] as OxcNode[] | undefined)?.[0],\n parameterNode['name'] as string\n );\n\n if (!prefixSegments) return;\n\n const scope: BindingScope = {\n ...getEnclosingScope(state, declaratorNode),\n declarationEnd: nodeEnd(declaratorNode),\n };\n const calleeNode = callNode['callee'] as OxcNode | undefined;\n const wrappedBinding =\n calleeNode?.['type'] === 'Identifier'\n ? resolveBinding(\n state.translatorBindings,\n calleeNode['name'] as string,\n nodeStart(callNode)\n )\n : undefined;\n\n if (wrappedBinding) {\n addBinding(state.translatorBindings, idNode['name'] as string, {\n ...wrappedBinding,\n keyPrefix: [...wrappedBinding.keyPrefix, ...prefixSegments],\n ...scope,\n });\n return;\n }\n\n const descriptor = matchDescriptorForCallee(\n state,\n calleeNode,\n (candidate) => candidate.translationFunction === 'self'\n );\n\n if (!descriptor) return;\n\n addBinding(state.translatorBindings, idNode['name'] as string, {\n // `null` = root scope: the first prefixed segment names the dictionary.\n dictionaryKey: readValueSources(callNode, descriptor.namespaceSources),\n keyPrefix: prefixSegments,\n descriptor,\n moduleSource: getModuleSource(state, descriptor),\n ...scope,\n });\n};\n\n/** Methods of a translation function that take a message id first. */\nconst TRANSLATOR_METHOD_NAMES = new Set(['rich', 'markup', 'raw', 'has']);\n\n/**\n * The translator identifier a call goes through: `t` in `t('id')` and in\n * `t.rich('id')`.\n */\nconst getTranslatorCalleeIdentifier = (\n calleeNode: OxcNode | undefined\n): OxcNode | null => {\n if (calleeNode?.['type'] === 'Identifier') return calleeNode;\n\n if (calleeNode?.['type'] !== 'MemberExpression' || calleeNode['computed']) {\n return null;\n }\n\n const objectNode = calleeNode['object'] as OxcNode | undefined;\n const propertyNode = calleeNode['property'] as OxcNode | undefined;\n\n return objectNode?.['type'] === 'Identifier' &&\n TRANSLATOR_METHOD_NAMES.has(propertyNode?.['name'] as string)\n ? objectNode\n : null;\n};\n\n/**\n * ngx-translate template forms, which live in HTML (component templates or\n * inline `template:` strings) and never reach the JS AST:\n * - `{{ 'home.title' | translate }}` pipe\n * - `[translate]=\"'home.title'\"` bound directive\n * - `translate=\"home.title\"` static directive\n * - `<h2 translate>home.title</h2>` directive keyed by the element text\n */\nconst TRANSLATE_PIPE_PATTERN =\n /(['\"])([^'\"\\r\\n{}|]+)\\1\\s*\\|\\s*translate\\b|\\[translate\\]\\s*=\\s*\"'([^'\"\\r\\n]+)'\"|\\stranslate\\s*=\\s*\"([^'\"\\r\\n{}]+)\"|<[\\w-]+(?:\\s[^<>]*)?\\stranslate(?=[\\s/>])[^<>]*>\\s*([^\\s<>{}]+)\\s*</g;\n\nconst collectTranslatePipeUsages = (text: string): MessageUsage[] => {\n if (!text.includes('translate')) return [];\n\n const usages: MessageUsage[] = [];\n\n for (const match of text.matchAll(TRANSLATE_PIPE_PATTERN)) {\n const elementTextKey = match[5];\n const split = splitMessageIdAtFirstSegment(\n match[2] ?? match[3] ?? match[4] ?? elementTextKey ?? ''\n );\n\n if (!split) continue;\n\n // Element-text form: span the key only, not the whole opening tag.\n const start = elementTextKey\n ? match.index + match[0].lastIndexOf(elementTextKey)\n : match.index;\n\n usages.push({\n ...split,\n start,\n end: elementTextKey\n ? start + elementTextKey.length\n : match.index + match[0].length,\n kind: 'call',\n callerName: 'translate',\n library: '@ngx-translate/core',\n });\n }\n\n return usages;\n};\n\n/**\n * Record `t('path.to.field')` calls on translator bindings, and self-caller\n * calls (`formatMessage({ id })`, `i18n._('id')`).\n */\nconst collectCallUsages = (state: AnalyzerState, program: OxcNode): void => {\n walkAst(program, (node) => {\n if (node['type'] === 'TaggedTemplateExpression') {\n collectTaggedTemplateUsage(state, node);\n return;\n }\n\n if (node['type'] !== 'CallExpression') return;\n\n const callee = node['callee'] as OxcNode | undefined;\n\n // Translator binding call: t('path.to.field'), or one of its methods\n // (next-intl `t.rich('path')`, `t.markup`, `t.raw`, `t.has`).\n const translatorNode = getTranslatorCalleeIdentifier(callee);\n\n if (translatorNode) {\n const binding = resolveBinding(\n state.translatorBindings,\n translatorNode['name'] as string,\n nodeStart(node)\n );\n\n if (binding) {\n const argumentsList = node['arguments'] as OxcNode[] | undefined;\n const messageId = getStaticStringValue(argumentsList?.[0]);\n\n if (messageId) {\n const { namespaceOverride, messagePath } =\n splitNamespacePrefixedId(messageId);\n let dictionaryKey = namespaceOverride ?? binding.dictionaryKey;\n let fieldPath = namespaceOverride\n ? messagePath.split('.')\n : [...binding.keyPrefix, ...messagePath.split('.')];\n\n // Root-scope translator (`useTranslations()`): the first id\n // segment is the dictionary key.\n if (dictionaryKey === null) {\n const split = splitMessageIdAtFirstSegment(\n [...binding.keyPrefix, messagePath].join('.')\n );\n dictionaryKey = split?.dictionaryKey ?? null;\n fieldPath = split?.fieldPath ?? [];\n }\n\n if (dictionaryKey) {\n state.usages.push({\n dictionaryKey,\n fieldPath,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'call',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n moduleSource: binding.moduleSource,\n });\n }\n }\n return;\n }\n }\n\n // Self caller: the call itself carries the message id.\n const descriptor = matchDescriptorForCallee(\n state,\n callee,\n (candidate) => candidate.translationFunction === 'self'\n );\n\n if (!descriptor) return;\n\n const messageId = getSelfCallMessageId(node);\n\n if (!messageId) return;\n\n const fixedDictionaryKey = readValueSources(\n node,\n descriptor.namespaceSources\n );\n const resolved = resolveMessageId(\n descriptor,\n fixedDictionaryKey,\n messageId\n );\n\n if (!resolved) return;\n\n state.usages.push({\n ...resolved,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'call',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n });\n};\n\n/**\n * Lingui macro tagged template: ``t`Hello ${name}` `` — the catalog id is the\n * template text with `{placeholder}` slots for each expression.\n */\nconst collectTaggedTemplateUsage = (\n state: AnalyzerState,\n node: OxcNode\n): void => {\n const descriptor = matchDescriptorForCallee(\n state,\n node['tag'] as OxcNode | undefined,\n (candidate) => candidate.matchAsTaggedTemplate === true\n );\n\n if (!descriptor) return;\n\n const quasiNode = node['quasi'] as OxcNode | undefined;\n const quasis = (quasiNode?.['quasis'] as OxcNode[]) ?? [];\n const expressions = (quasiNode?.['expressions'] as OxcNode[]) ?? [];\n\n let messageId = '';\n\n for (let index = 0; index < quasis.length; index++) {\n const valueNode = quasis[index]?.['value'] as OxcNode | undefined;\n messageId +=\n (valueNode?.['cooked'] as string) ?? (valueNode?.['raw'] as string) ?? '';\n\n if (index < expressions.length) {\n const expression = expressions[index]!;\n const placeholder =\n expression['type'] === 'Identifier'\n ? (expression['name'] as string)\n : String(index);\n messageId += `{${placeholder}}`;\n }\n }\n\n if (!messageId) return;\n\n const fixedDictionaryKey = readValueSources(\n node,\n descriptor.namespaceSources\n );\n const resolved = resolveMessageId(descriptor, fixedDictionaryKey, messageId);\n\n if (!resolved) return;\n\n state.usages.push({\n ...resolved,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'tagged-template',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n};\n\n/** Read a static string JSX attribute from an opening element. */\nconst getJsxAttributeString = (\n openingElement: OxcNode,\n attributeName: string\n): string | null => {\n for (const attribute of (openingElement['attributes'] as OxcNode[]) ?? []) {\n if (attribute['type'] !== 'JSXAttribute') continue;\n\n const nameNode = attribute['name'] as OxcNode | undefined;\n\n if ((nameNode?.['name'] as string) !== attributeName) continue;\n\n const valueNode = attribute['value'] as OxcNode | undefined;\n\n if (!valueNode) return null;\n\n // <Trans i18nKey=\"key\" /> or <Trans i18nKey={'key'} />\n const directValue = getStaticStringValue(valueNode);\n\n if (directValue !== null) return directValue;\n\n if (valueNode['type'] === 'JSXExpressionContainer') {\n return getStaticStringValue(\n valueNode['expression'] as OxcNode | undefined\n );\n }\n\n return null;\n }\n\n return null;\n};\n\n/**\n * Record JSX message components: `<FormattedMessage id=\"home.title\" />`,\n * `<Trans i18nKey=\"richText\" />`, `<Trans id=\"…\" />`.\n */\nconst collectJsxUsages = (state: AnalyzerState, program: OxcNode): void => {\n // Fallback namespace for JSX components without an explicit one: the single\n // distinct translator namespace declared in the file (react-i18next Trans).\n const translatorNamespaces = new Set(\n [...state.translatorBindings.values()]\n .flat()\n .map((binding) => binding.dictionaryKey)\n .filter(\n (dictionaryKey): dictionaryKey is string => dictionaryKey !== null\n )\n );\n const fallbackNamespace =\n translatorNamespaces.size === 1 ? [...translatorNamespaces][0]! : null;\n\n walkAst(program, (node) => {\n if (node['type'] !== 'JSXOpeningElement') return;\n\n const nameNode = node['name'] as OxcNode | undefined;\n\n if (nameNode?.['type'] !== 'JSXIdentifier') return;\n\n const elementName = nameNode['name'] as string;\n\n for (const descriptor of state.activeDescriptors) {\n if (!descriptor.jsxIdAttribute) continue;\n\n if (descriptor.callerName !== elementName) continue;\n\n const messageId = getJsxAttributeString(node, descriptor.jsxIdAttribute);\n\n if (messageId === null) continue;\n\n const namespaceFromAttribute = descriptor.jsxNamespaceAttribute\n ? getJsxAttributeString(node, descriptor.jsxNamespaceAttribute)\n : null;\n const fixedNamespace = descriptor.namespaceSources.find(\n (source) => source.from === 'fixed'\n );\n const dictionaryKey =\n namespaceFromAttribute ??\n (fixedNamespace?.from === 'fixed' ? fixedNamespace.value : null) ??\n fallbackNamespace;\n\n let resolved: { dictionaryKey: string; fieldPath: string[] } | null;\n\n if (dictionaryKey) {\n resolved = {\n dictionaryKey,\n fieldPath: descriptor.flatKey ? [messageId] : messageId.split('.'),\n };\n } else {\n // No namespace anywhere (`<Trans i18nKey=\"home.title\" />` under a\n // root-scope `useTranslation()`): the first id segment names the\n // dictionary, as for root-scope `t()` calls.\n resolved =\n resolveMessageId(descriptor, null, messageId) ??\n splitMessageIdAtFirstSegment(messageId);\n }\n\n if (!resolved) continue;\n\n state.usages.push({\n ...resolved,\n start: nodeStart(node),\n end: nodeEnd(node),\n kind: 'jsx',\n callerName: descriptor.callerName,\n library: descriptor.library,\n moduleSource: getModuleSource(state, descriptor),\n });\n return;\n }\n });\n};\n\n/** Identifier positions that are declarations, not references. */\nconst isDeclarationPosition = (\n identifierNode: OxcNode,\n parentMap: Map<OxcNode, OxcNode>\n): boolean => {\n const parent = parentMap.get(identifierNode);\n\n if (!parent) return false;\n\n const parentType = parent['type'] as string;\n\n if (parentType === 'VariableDeclarator' && parent['id'] === identifierNode) {\n return true;\n }\n\n if (\n (parentType === 'Property' || parentType === 'ObjectProperty') &&\n parentMap.get(parent)?.['type'] === 'ObjectPattern'\n ) {\n return true;\n }\n\n if (parentType === 'ImportSpecifier' || parentType === 'PropertyDefinition') {\n return true;\n }\n\n if (\n parentType === 'FunctionDeclaration' ||\n parentType === 'FunctionExpression' ||\n parentType === 'ArrowFunctionExpression'\n ) {\n return true;\n }\n\n // Object-literal keys: { title: … }\n if (\n (parentType === 'Property' || parentType === 'ObjectProperty') &&\n parent['key'] === identifierNode &&\n parentMap.get(parent)?.['type'] === 'ObjectExpression'\n ) {\n return true;\n }\n\n return false;\n};\n\n/** Identifier used as the (non-computed) property name of a member access. */\nconst isPropertyNamePosition = (\n identifierNode: OxcNode,\n parentMap: Map<OxcNode, OxcNode>\n): boolean => {\n const parent = parentMap.get(identifierNode);\n\n if (!parent) return false;\n\n const parentType = parent['type'] as string;\n\n return (\n (parentType === 'MemberExpression' &&\n parent['property'] === identifierNode &&\n parent['computed'] !== true) ||\n (parentType === 'JSXMemberExpression' &&\n parent['property'] === identifierNode)\n );\n};\n\n/**\n * Record member-access / bare-reference usages of content bindings:\n * `content.section.title`, `{title}` (destructured field reference),\n * Svelte's `$content.title`, Vue's `content.value.title`.\n */\nconst collectMemberUsages = (\n state: AnalyzerState,\n program: OxcNode,\n parentMap: Map<OxcNode, OxcNode>\n): void => {\n if (state.contentBindings.size === 0) return;\n\n walkAst(program, (node) => {\n const nodeType = node['type'] as string;\n\n if (nodeType !== 'Identifier' && nodeType !== 'JSXIdentifier') return;\n\n const rawName = node['name'] as string;\n // Svelte store sugar: `$content` reads the `content` store.\n const variableName = rawName.startsWith('$') ? rawName.slice(1) : rawName;\n const binding = resolveBinding(\n state.contentBindings,\n variableName,\n nodeStart(node)\n );\n\n if (!binding) return;\n\n // Skip identifiers in non-value positions: TypeScript type annotations\n // (`useIntlayer<{ greet: string }>`) and JSX attribute names.\n const parentType = parentMap.get(node)?.['type'] as string | undefined;\n\n if (parentType?.startsWith('TS') || parentType === 'JSXAttribute') return;\n\n if (isDeclarationPosition(node, parentMap)) return;\n\n if (isPropertyNamePosition(node, parentMap)) return;\n\n // Climb the member chain upward, collecting property segments.\n const fieldPath = [...binding.basePath];\n const fieldSpans: { start: number; end: number }[] = fieldPath.map(() => ({\n start: nodeStart(node),\n end: nodeEnd(node),\n }));\n\n let currentNode: OxcNode = node;\n\n while (true) {\n const parent = parentMap.get(currentNode);\n\n if (!parent) break;\n\n const parentType = parent['type'] as string;\n const isMemberAccess =\n (parentType === 'MemberExpression' &&\n parent['object'] === currentNode &&\n parent['computed'] !== true) ||\n (parentType === 'JSXMemberExpression' &&\n parent['object'] === currentNode);\n\n if (isMemberAccess) {\n const propertyNode = parent['property'] as OxcNode;\n const propertyName = propertyNode['name'] as string;\n\n if (!ACCESSOR_PROPERTY_NAMES.has(propertyName)) {\n fieldPath.push(propertyName);\n fieldSpans.push({\n start: nodeStart(propertyNode),\n end: nodeEnd(propertyNode),\n });\n }\n currentNode = parent;\n continue;\n }\n\n // Computed string access: content['title']\n if (\n parentType === 'MemberExpression' &&\n parent['object'] === currentNode &&\n parent['computed'] === true\n ) {\n const propertyValue = getStaticStringValue(\n parent['property'] as OxcNode | undefined\n );\n\n if (propertyValue === null) break;\n\n fieldPath.push(propertyValue);\n fieldSpans.push({\n start: nodeStart(parent['property'] as OxcNode),\n end: nodeEnd(parent['property'] as OxcNode),\n });\n currentNode = parent;\n continue;\n }\n\n // Call of an accessor / chain terminator: content.title.use()\n if (parentType === 'CallExpression' && parent['callee'] === currentNode) {\n currentNode = parent;\n continue;\n }\n\n break;\n }\n\n state.usages.push({\n dictionaryKey: binding.dictionaryKey,\n fieldPath,\n fieldSpans,\n start: nodeStart(node),\n end: nodeEnd(currentNode),\n kind: 'member',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n moduleSource: binding.moduleSource,\n // No explicit property segment: the usage only names the variable.\n isBareReference: fieldPath.length === binding.basePath.length,\n });\n return true;\n });\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Analyse a source file and return every resolvable translation usage:\n * base-intlayer content access and all compat-library forms (translation\n * functions, self calls, JSX message components, tagged templates).\n *\n * Pure and self-contained (oxc parse only) — shared by the LSP handlers and\n * the VS Code extension providers/decorations.\n *\n * @param text - Full source text (a script: TS/TSX or an extracted SFC block).\n * @returns Usages ordered by start offset.\n */\nexport const collectMessageUsages = (text: string): MessageUsage[] => {\n const pipeUsages = collectTranslatePipeUsages(text);\n const program = parseText(text);\n\n if (!program) return pipeUsages;\n\n const fileImportSources = collectImportSources(program);\n const parentMap = buildParentMap(program);\n const state: AnalyzerState = {\n usages: [],\n translatorBindings: new Map(),\n contentBindings: new Map(),\n activeDescriptors: ANALYZED_CALLERS.filter((descriptor) =>\n isCallerActive(descriptor, fileImportSources)\n ),\n importedLocalNames: collectImportedLocalNames(program),\n parentMap,\n program,\n };\n\n collectBindings(state, program);\n collectCallUsages(state, program);\n collectJsxUsages(state, program);\n collectMemberUsages(state, program, parentMap);\n\n return [...state.usages, ...pipeUsages].sort(\n (first, second) => first.start - second.start\n );\n};\n\n/**\n * Resolve the dictionary key declared by a single call-expression node when\n * it matches any registered non-self caller (`useIntlayer(\"key\")`,\n * `useI18n({ namespace })`, …). Used for on-the-fly checks where the full\n * file analysis is not needed (e.g. completion context).\n *\n * @param callNode - A candidate CallExpression node.\n */\nexport const matchCallNamespace = (callNode: OxcNode): string | null => {\n if (callNode['type'] !== 'CallExpression') return null;\n\n const callee = getCalleeName(callNode['callee'] as OxcNode | undefined);\n\n if (!callee) return null;\n\n for (const descriptor of ALL_CALLERS) {\n if (descriptor.translationFunction === 'self') continue;\n\n if (descriptor.callerName !== callee.name) continue;\n\n if (callee.isMethod && !descriptor.matchAsMethod) continue;\n\n const namespaceValue = readValueSources(\n callNode,\n descriptor.namespaceSources\n );\n\n if (namespaceValue !== null) {\n return splitNestedNamespace(descriptor, namespaceValue).dictionaryKey;\n }\n }\n\n return null;\n};\n\n/**\n * A call site declaring which dictionary a caller reads\n * (`useIntlayer(\"home\")`, `useI18n({ namespace: 'home' })`), with the spans\n * needed to anchor diagnostics and cursor checks.\n */\nexport type NamespaceReference = {\n dictionaryKey: string;\n callerName: string;\n library: string;\n /** Span of the whole call expression. */\n callStart: number;\n callEnd: number;\n /** Span of the matched callee name (identifier or method property). */\n calleeStart: number;\n calleeEnd: number;\n /** Span of the namespace argument (string literal or option value). */\n namespaceStart: number;\n namespaceEnd: number;\n};\n\n/**\n * The AST node holding the namespace string for a given value source, when\n * that source is addressable in the call (positional argument or options\n * property).\n */\nconst getNamespaceArgumentNode = (\n callNode: OxcNode,\n source: CallerValueSource\n): OxcNode | null => {\n const argumentsList = callNode['arguments'] as OxcNode[] | undefined;\n\n if (source.from === 'argument') {\n return argumentsList?.[source.index] ?? null;\n }\n\n if (source.from === 'option') {\n const property = getObjectPropertyNode(\n argumentsList?.[source.argumentIndex],\n source.property\n );\n\n return (property?.['value'] as OxcNode | undefined) ?? null;\n }\n\n return null;\n};\n\n/**\n * Collect every call site with an addressable namespace argument (positional\n * or options property) resolving to a static string. Powers the\n * unknown-dictionary diagnostics and `findKeyAtOffset`.\n *\n * Self callers (`formatMessage`, lingui `t`/`_`) don't declare a namespace at\n * the call site and are excluded.\n *\n * @param text - Full source text.\n */\nexport const collectNamespaceReferences = (\n text: string\n): NamespaceReference[] => {\n const program = parseText(text);\n\n if (!program) return [];\n\n const fileImportSources = collectImportSources(program);\n const activeDescriptors = ANALYZED_CALLERS.filter(\n (descriptor) =>\n descriptor.translationFunction !== 'self' &&\n isCallerActive(descriptor, fileImportSources)\n );\n const references: NamespaceReference[] = [];\n\n walkAst(program, (node) => {\n if (node['type'] !== 'CallExpression') return;\n\n const calleeNode = node['callee'] as OxcNode | undefined;\n const callee = getCalleeName(calleeNode);\n\n if (!callee) return;\n\n for (const descriptor of activeDescriptors) {\n if (descriptor.callerName !== callee.name) continue;\n\n if (callee.isMethod && !descriptor.matchAsMethod) continue;\n\n const calleeNameNode =\n callee.isMethod && calleeNode\n ? (calleeNode['property'] as OxcNode)\n : calleeNode!;\n\n for (const source of descriptor.namespaceSources) {\n const namespaceNode = getNamespaceArgumentNode(node, source);\n const namespaceValue = getStaticStringValue(namespaceNode ?? undefined);\n\n if (!namespaceNode || namespaceValue === null) continue;\n\n references.push({\n dictionaryKey: splitNestedNamespace(descriptor, namespaceValue)\n .dictionaryKey,\n callerName: descriptor.callerName,\n library: descriptor.library,\n callStart: nodeStart(node),\n callEnd: nodeEnd(node),\n calleeStart: nodeStart(calleeNameNode),\n calleeEnd: nodeEnd(calleeNameNode),\n namespaceStart: nodeStart(namespaceNode),\n namespaceEnd: nodeEnd(namespaceNode),\n });\n return;\n }\n }\n });\n\n return references;\n};\n\n/**\n * A source variable bound to a dictionary by a caller declaration:\n * dictionary content (or a field subtree of it) for `content` callers, or a\n * translation function for `return-value` / `destructured-t` callers.\n */\nexport type CallerVariableBinding = {\n /** Local variable name. */\n variableName: string;\n /** The dictionary the variable reads from. */\n dictionaryKey: string;\n /**\n * Field path from the dictionary root the variable points at (content\n * bindings), or the key prefix applied to every call (translator bindings).\n */\n basePath: string[];\n /** Whether the variable holds content or a translation function. */\n bindingKind: 'content' | 'translator';\n /** The caller that created the binding. */\n callerName: string;\n library: string;\n};\n\n/**\n * Collect every variable bound to a dictionary in the file. Used by consumers\n * that scan non-script regions (Vue/Angular templates) for references to\n * those variables, or that need to know which dictionaries a file consumes.\n *\n * @param text - Full source text (a script: TS/TSX or an extracted SFC block).\n */\nexport const collectCallerBindings = (\n text: string\n): CallerVariableBinding[] => {\n const program = parseText(text);\n\n if (!program) return [];\n\n const fileImportSources = collectImportSources(program);\n const state: AnalyzerState = {\n usages: [],\n translatorBindings: new Map(),\n contentBindings: new Map(),\n activeDescriptors: ANALYZED_CALLERS.filter((descriptor) =>\n isCallerActive(descriptor, fileImportSources)\n ),\n importedLocalNames: collectImportedLocalNames(program),\n parentMap: buildParentMap(program),\n program,\n };\n\n collectBindings(state, program);\n\n return [\n ...[...state.contentBindings.entries()].flatMap(\n ([variableName, bindings]) =>\n bindings.map((binding): CallerVariableBinding => ({\n variableName,\n dictionaryKey: binding.dictionaryKey,\n basePath: binding.basePath,\n bindingKind: 'content',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n }))\n ),\n ...[...state.translatorBindings.entries()].flatMap(\n ([variableName, bindings]) =>\n bindings\n // Root-scope translators have no bound dictionary to expose.\n .filter((binding) => binding.dictionaryKey !== null)\n .map((binding): CallerVariableBinding => ({\n variableName,\n dictionaryKey: binding.dictionaryKey!,\n basePath: binding.keyPrefix,\n bindingKind: 'translator',\n callerName: binding.descriptor.callerName,\n library: binding.descriptor.library,\n }))\n ),\n ];\n};\n\n/**\n * Find the most specific translation usage at `offset`.\n *\n * For member chains the field path is trimmed to the segment under the\n * cursor: hovering `section` in `content.section.title` yields\n * `['section']`, not the full chain.\n *\n * Dictionary-level `namespace` usages are only returned when no field-level\n * usage matches the offset.\n *\n * @param text - Full source text.\n * @param offset - Cursor offset in `text`.\n */\nexport const findMessageUsageAtOffset = (\n text: string,\n offset: number\n): MessageUsage | null => {\n const usages = collectMessageUsages(text);\n\n let bestMatch: MessageUsage | null = null;\n\n for (const usage of usages) {\n if (offset < usage.start || offset > usage.end) continue;\n\n const isBetter =\n !bestMatch ||\n // Prefer field-level usages over dictionary-level ones…\n (bestMatch.kind === 'namespace' && usage.kind !== 'namespace') ||\n // …then the smallest span containing the offset.\n (usage.end - usage.start < bestMatch.end - bestMatch.start &&\n !(bestMatch.kind !== 'namespace' && usage.kind === 'namespace'));\n\n if (isBetter) bestMatch = usage;\n }\n\n if (!bestMatch) return null;\n\n // Trim member chains to the segment under the cursor.\n if (bestMatch.kind === 'member' && bestMatch.fieldSpans) {\n let lastIncludedIndex = -1;\n\n for (let index = 0; index < bestMatch.fieldSpans.length; index++) {\n if (offset >= bestMatch.fieldSpans[index]!.start) {\n lastIncludedIndex = index;\n }\n }\n\n return {\n ...bestMatch,\n fieldPath: bestMatch.fieldPath.slice(0, lastIncludedIndex + 1),\n fieldSpans: bestMatch.fieldSpans.slice(0, lastIncludedIndex + 1),\n };\n }\n\n return bestMatch;\n};\n"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- import { buildParentMap, getFirstStringArg, getObjectPropertyNode, getObjectPropertyString, getPropertyKeyName, getStaticStringValue, getStringArgAt, isStringLiteralNode, nodeContainsOffset, nodeEnd, nodeStart, parseText, walkAst } from "./oxcUtils.mjs";
2
- import { DICTIONARIES_NOT_BUILT_NOTIFICATION } from "./protocol.mjs";
3
1
  import { callers_exports } from "./callers/index.mjs";
4
- import { collectCallerBindings, collectMessageUsages, collectNamespaceReferences, findMessageUsageAtOffset, matchCallNamespace } from "./usageAnalyzer.mjs";
5
- import { escapeRegularExpression, findFieldRangesInFile, offsetToRange } from "./findFieldInFile.mjs";
6
- import { findFieldDeclaration } from "./findFieldDeclaration.mjs";
7
- import { findContentPath, getUsageTargetCandidates, resolveDictionaryTarget } from "./resolveDictionaryTarget.mjs";
8
2
  import { buildCallerWithKeyPattern, buildKeyUsagePatterns, getCallerNamesAlternation } from "./callers/patterns.mjs";
3
+ import { findFieldDeclaration } from "./findFieldDeclaration.mjs";
4
+ import { escapeRegularExpression, findFieldRangesInFile, offsetToRange } from "./findFieldInFile.mjs";
9
5
  import { findKeyAtOffset } from "./findKeyAtOffset.mjs";
10
6
  import { findContentFieldAtOffset, findKeyInContentFile } from "./findKeyInContentFile.mjs";
11
- import { findUsageFieldAtOffset } from "./findUsageFieldAtOffset.mjs";
12
7
  import { findTCallAtOffset } from "./findTCallAtOffset.mjs";
8
+ import { findUsageFieldAtOffset } from "./findUsageFieldAtOffset.mjs";
9
+ import { buildParentMap, getFirstStringArg, getObjectPropertyNode, getObjectPropertyString, getPropertyKeyName, getStaticStringValue, getStringArgAt, isStringLiteralNode, nodeContainsOffset, nodeEnd, nodeStart, parseText, walkAst } from "./oxcUtils.mjs";
10
+ import { DICTIONARIES_NOT_BUILT_NOTIFICATION } from "./protocol.mjs";
11
+ import { findContentPath, getUsageTargetCandidates, resolveDictionaryTarget } from "./resolveDictionaryTarget.mjs";
12
+ import { collectCallerBindings, collectMessageUsages, collectNamespaceReferences, findMessageUsageAtOffset, matchCallNamespace } from "./usageAnalyzer.mjs";
13
13
 
14
14
  var ALL_CALLERS = callers_exports.ALL_CALLERS;
15
15
  var BASE_CALLERS = callers_exports.BASE_CALLERS;
@@ -1,5 +1,4 @@
1
1
  import { CallerDescriptor } from "@intlayer/config/callers";
2
- //#region src/callers/editorCallers.d.ts
3
2
  /**
4
3
  * Callers recognised by the editor tooling only (go-to-definition, hover,
5
4
  * references) — deliberately kept out of the shared registry in
@@ -11,5 +10,4 @@ import { CallerDescriptor } from "@intlayer/config/callers";
11
10
  * (`index`) when that segment names no dictionary.
12
11
  */
13
12
  export declare const EDITOR_CALLERS: CallerDescriptor[];
14
- //#endregion
15
13
  //# sourceMappingURL=editorCallers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"editorCallers.d.ts","names":[],"sources":["../../../src/callers/editorCallers.ts"],"mappings":";;;;;;;;;;;;qBAwBa,gBAAgB"}
1
+ {"version":3,"file":"editorCallers.d.ts","names":[],"sources":["../../../src/callers/editorCallers.ts"],"mappings":";;;;;;;;;;;qBAwBa,gBAAgB"}
@@ -1,5 +1,16 @@
1
+ /**
2
+ * Caller registry — re-exported from the shared source of truth in
3
+ * `@intlayer/config/callers`.
4
+ *
5
+ * The descriptors are shared with `@intlayer/babel` (usage analysis + optimize
6
+ * rewrite), `@intlayer/swc` (via `toSwcExtraCallers`) and every compat
7
+ * package's bundler plugin, so a compat library declared once in
8
+ * `@intlayer/config/src/callers/compat/<lib>.ts` is supported everywhere.
9
+ *
10
+ * Editor-specific matching helpers built on top of the registry live in
11
+ * `./patterns.ts`.
12
+ */
1
13
  export * from "@intlayer/config/callers";
2
14
  import * as import__intlayer_config_callers from "@intlayer/config/callers";
3
- //#endregion
4
15
  export { import__intlayer_config_callers as index_d_exports };
5
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/callers/index.ts"],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":[],"mappings":""}
@@ -1,4 +1,3 @@
1
- //#region src/callers/patterns.d.ts
2
1
  /**
3
2
  * Alternation of every caller name whose dictionary key appears as a
4
3
  * positional string argument — for building text-search patterns.
@@ -25,5 +24,4 @@ export declare const buildKeyUsagePatterns: (key: string) => RegExp[];
25
24
  * @param key - The dictionary key.
26
25
  */
27
26
  export declare const buildCallerWithKeyPattern: (key: string) => RegExp;
28
- //#endregion
29
27
  //# sourceMappingURL=patterns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"patterns.d.ts","names":[],"sources":["../../../src/callers/patterns.ts"],"mappings":";;;;;qBAOa;;;;;;;;;;;;;;qBAgBA,wBAAyB,gBAAc;;;;;;;qBAqBvC,4BAA6B,gBAAc"}
1
+ {"version":3,"file":"patterns.d.ts","names":[],"sources":["../../../src/callers/patterns.ts"],"mappings":";;;;qBAOa;;;;;;;;;;;;;;qBAgBA,wBAAyB,gBAAc;;;;;;;qBAqBvC,4BAA6B,gBAAc"}
@@ -1,10 +1,8 @@
1
1
  import { Dictionary } from "@intlayer/types/dictionary";
2
- //#region src/dictionaryUtils.d.ts
3
2
  export declare const formatFieldValue: (value: unknown) => string;
4
3
  export declare const getFieldByPath: (content: unknown, path: string[]) => unknown;
5
4
  export declare const getTopLevelFields: (content: unknown) => string[];
6
5
  export declare const getFieldsAtPath: (content: unknown, path: string[]) => string[];
7
6
  export declare const formatDictionaryHover: (dictionaries: Dictionary[], key: string) => string;
8
7
  export declare const formatFieldHover: (dictionaries: Dictionary[], dictionaryKey: string, fieldPath: string[]) => string | null;
9
- //#endregion
10
8
  //# sourceMappingURL=dictionaryUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dictionaryUtils.d.ts","names":[],"sources":["../../src/dictionaryUtils.ts"],"mappings":";;qBAoDa,mBAAoB;qBAoBpB,iBAAkB,kBAAkB;qBAYpC,oBAAqB;qBAKrB,kBAAmB,kBAAkB;qBASrC,wBACX,cAAc,cACd;qBAyBW,mBACX,cAAc,cACd,uBACA"}
1
+ {"version":3,"file":"dictionaryUtils.d.ts","names":[],"sources":["../../src/dictionaryUtils.ts"],"mappings":";qBAoDa,mBAAoB;qBAoBpB,iBAAkB,kBAAkB;qBAYpC,oBAAqB;qBAKrB,kBAAmB,kBAAkB;qBASrC,wBACX,cAAc,cACd;qBAyBW,mBACX,cAAc,cACd,uBACA"}
@@ -1,4 +1,3 @@
1
- //#region src/findFieldDeclaration.d.ts
2
1
  /** Offsets of a declaration inside a file's text. */
3
2
  export type OffsetSpan = {
4
3
  start: number;
@@ -20,5 +19,4 @@ export type OffsetSpan = {
20
19
  * @returns The span of the property key, or `null` when not found.
21
20
  */
22
21
  export declare const findFieldDeclaration: (text: string, filePath: string, dictionaryKey: string, fieldPath: string[]) => OffsetSpan | null;
23
- //#endregion
24
22
  //# sourceMappingURL=findFieldDeclaration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findFieldDeclaration.d.ts","names":[],"sources":["../../src/findFieldDeclaration.ts"],"mappings":";;YAWY;EAAe;EAAe;;;;;;;;;;;;;;;;;qBAuN7B,uBACX,cACA,kBACA,uBACA,wBACC"}
1
+ {"version":3,"file":"findFieldDeclaration.d.ts","names":[],"sources":["../../src/findFieldDeclaration.ts"],"mappings":";YAWY;EAAe;EAAe;;;;;;;;;;;;;;;;;qBAuN7B,uBACX,cACA,kBACA,uBACA,wBACC"}
@@ -1,5 +1,4 @@
1
1
  import { Range } from "vscode-languageserver/node";
2
- //#region src/findFieldInFile.d.ts
3
2
  export declare const escapeRegularExpression: (content: string) => string;
4
3
  export declare const offsetToRange: (text: string, start: number, end: number) => Range;
5
4
  /**
@@ -22,5 +21,4 @@ export declare const offsetToRange: (text: string, start: number, end: number) =
22
21
  * backward compatibility.
23
22
  */
24
23
  export declare const findFieldRangesInFile: (text: string, escapedKey: string, _fieldName: string, escapedField: string, fieldPath?: string[]) => Range[];
25
- //#endregion
26
24
  //# sourceMappingURL=findFieldInFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findFieldInFile.d.ts","names":[],"sources":["../../src/findFieldInFile.ts"],"mappings":";;qBAGa,0BAA2B;qBAG3B,gBACX,cACA,eACA,gBACC;;;;;;;;;;;;;;;;;;;;qBAiCU,wBACX,cACA,oBACA,oBACA,sBACA,yBACC"}
1
+ {"version":3,"file":"findFieldInFile.d.ts","names":[],"sources":["../../src/findFieldInFile.ts"],"mappings":";qBAGa,0BAA2B;qBAG3B,gBACX,cACA,eACA,gBACC;;;;;;;;;;;;;;;;;;;;qBAiCU,wBACX,cACA,oBACA,oBACA,sBACA,yBACC"}
@@ -1,4 +1,3 @@
1
- //#region src/findKeyAtOffset.d.ts
2
1
  /**
3
2
  * Scan `text` for a caller whose namespace (dictionary key) is addressed at
4
3
  * `offset`. Returns the namespace string when the cursor is on the caller
@@ -16,5 +15,4 @@
16
15
  * namespace declarations — they are resolved by `findMessageUsageAtOffset`.
17
16
  */
18
17
  export declare const findKeyAtOffset: (text: string, offset: number) => string | null;
19
- //#endregion
20
18
  //# sourceMappingURL=findKeyAtOffset.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findKeyAtOffset.d.ts","names":[],"sources":["../../src/findKeyAtOffset.ts"],"mappings":";;;;;;;;;;;;;;;;;qBAkBa,kBACX,cACA"}
1
+ {"version":3,"file":"findKeyAtOffset.d.ts","names":[],"sources":["../../src/findKeyAtOffset.ts"],"mappings":";;;;;;;;;;;;;;;;qBAkBa,kBACX,cACA"}
@@ -1,4 +1,3 @@
1
- //#region src/findKeyInContentFile.d.ts
2
1
  /**
3
2
  * If `offset` falls within a `key:` declaration in a content file,
4
3
  * return the declared key string; otherwise return null.
@@ -28,5 +27,5 @@ type FieldResult = {
28
27
  fieldName: string;
29
28
  fieldPath: string[];
30
29
  };
31
- //#endregion
30
+ export {};
32
31
  //# sourceMappingURL=findKeyInContentFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findKeyInContentFile.d.ts","names":[],"sources":["../../src/findKeyInContentFile.ts"],"mappings":";;;;;;;;;qBAea,uBACX,cACA;;;;;;;;;;;;;;;qBA4BW,2BACX,cACA,gBACA,2BACC;KA4LE;EACH;EACA;EACA"}
1
+ {"version":3,"file":"findKeyInContentFile.d.ts","names":[],"sources":["../../src/findKeyInContentFile.ts"],"mappings":";;;;;;;;qBAea,uBACX,cACA;;;;;;;;;;;;;;;qBA4BW,2BACX,cACA,gBACA,2BACC;KA4LE;EACH;EACA;EACA"}
@@ -1,4 +1,3 @@
1
- //#region src/findTCallAtOffset.d.ts
2
1
  /**
3
2
  * Detect when the cursor is on a message usage carrying an explicit id: a
4
3
  * `t('key')` call from any translator caller, a self call
@@ -19,5 +18,4 @@ export declare const findTCallAtOffset: (text: string, offset: number) => {
19
18
  dictionaryKey: string;
20
19
  fieldName: string;
21
20
  } | null;
22
- //#endregion
23
21
  //# sourceMappingURL=findTCallAtOffset.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findTCallAtOffset.d.ts","names":[],"sources":["../../src/findTCallAtOffset.ts"],"mappings":";;;;;;;;;;;;;;;;;qBAkBa,oBACX,cACA;EACG;EAAuB"}
1
+ {"version":3,"file":"findTCallAtOffset.d.ts","names":[],"sources":["../../src/findTCallAtOffset.ts"],"mappings":";;;;;;;;;;;;;;;;qBAkBa,oBACX,cACA;EACG;EAAuB"}
@@ -1,4 +1,3 @@
1
- //#region src/findUsageFieldAtOffset.d.ts
2
1
  /**
3
2
  * Detect when the cursor is on a field name that was obtained from a
4
3
  * useIntlayer / getIntlayer call in the same file. Two patterns:
@@ -18,5 +17,4 @@ export declare const findUsageFieldAtOffset: (text: string, offset: number) => {
18
17
  dictionaryKey: string;
19
18
  fieldName: string;
20
19
  } | null;
21
- //#endregion
22
20
  //# sourceMappingURL=findUsageFieldAtOffset.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findUsageFieldAtOffset.d.ts","names":[],"sources":["../../src/findUsageFieldAtOffset.ts"],"mappings":";;;;;;;;;;;;;;;;qBAiBa,yBACX,cACA;EACG;EAAuB"}
1
+ {"version":3,"file":"findUsageFieldAtOffset.d.ts","names":[],"sources":["../../src/findUsageFieldAtOffset.ts"],"mappings":";;;;;;;;;;;;;;;qBAiBa,yBACX,cACA;EACG;EAAuB"}
@@ -1,4 +1,3 @@
1
- //#region src/oxcUtils.d.ts
2
1
  export type OxcNode = Record<string, unknown>;
3
2
  /**
4
3
  * Parse `text` into an Oxc program AST.
@@ -48,5 +47,4 @@ export declare const getObjectPropertyNode: (objectExpression: OxcNode | undefin
48
47
  export declare const getObjectPropertyString: (objectExpression: OxcNode | undefined, propertyName: string) => string | null;
49
48
  /** Get the identifier or string name of an object-property key node. */
50
49
  export declare const getPropertyKeyName: (keyNode: OxcNode | undefined) => string | null;
51
- //#endregion
52
50
  //# sourceMappingURL=oxcUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oxcUtils.d.ts","names":[],"sources":["../../src/oxcUtils.ts"],"mappings":";YAEY,UAAU;;;;;;;qBAQT,YAAa,iBAAe;;;;;qBAc5B,UACX,eAEA,UAAU,MAAM;;;;;qBAyBL,iBAAkB,MAAM,YAAU,IAAI,SAAS;;qBA4B/C,YAAa,MAAM;;qBAMnB,UAAW,MAAM;;qBAMjB,qBAAsB,MAAM,SAAS;;;;;qBAOrC,sBAAuB,MAAM;;;;;qBAkB7B,uBACX,MAAM;;qBA8BK,iBACX,UAAU,SACV;;qBAUW,oBAAqB,oBAAoB;;;;qBAMzC,wBACX,kBAAkB,qBAClB,yBACC;;;;;qBA4BU,0BACX,kBAAkB,qBAClB;;qBAUW,qBACX,SAAS"}
1
+ {"version":3,"file":"oxcUtils.d.ts","names":[],"sources":["../../src/oxcUtils.ts"],"mappings":"A,YAEY,UAAU;;;;;;;qBAQT,YAAa,iBAAe;;;;;qBAc5B,UACX,eAEA,UAAU,MAAM;;;;;qBAyBL,iBAAkB,MAAM,YAAU,IAAI,SAAS;;qBA4B/C,YAAa,MAAM;;qBAMnB,UAAW,MAAM;;qBAMjB,qBAAsB,MAAM,SAAS;;;;;qBAOrC,sBAAuB,MAAM;;;;;qBAkB7B,uBACX,MAAM;;qBA8BK,iBACX,UAAU,SACV;;qBAUW,oBAAqB,oBAAoB;;;;qBAMzC,wBACX,kBAAkB,qBAClB,yBACC;;;;;qBA4BU,0BACX,kBAAkB,qBAClB;;qBAUW,qBACX,SAAS"}
@@ -1,4 +1,3 @@
1
- //#region src/protocol.d.ts
2
1
  /**
3
2
  * Custom notifications the Intlayer language server sends to its client, on
4
3
  * top of the standard LSP surface. Kept in a dedicated module so the client
@@ -21,5 +20,4 @@ export type DictionariesNotBuiltParams = {
21
20
  /** Root directory of the project whose dictionaries are missing. */
22
21
  baseDir: string;
23
22
  };
24
- //#endregion
25
23
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","names":[],"sources":["../../src/protocol.ts"],"mappings":";;;;;;;;;;;;;;;;;qBAiBa;;YAID;;EAEV"}
1
+ {"version":3,"file":"protocol.d.ts","names":[],"sources":["../../src/protocol.ts"],"mappings":";;;;;;;;;;;;;;;;qBAiBa;;YAID;;EAEV"}