definitionInScratch
uses tcmts.studio.editableCodebase, which uses tcmts.share.servedCodebase, which uses process
Where the name at offset in a scratch file is defined: a name from the codebase, its page; one the file declares,
where (an offset); one from elsewhere (a package, the standard library), nowhere here.
import { cacheRefOf } from "#codebase/tcmts/core/shape"; import { declarationOf } from "#codebase/tcmts/core/ts"; import { codeHref } from "#codebase/tcmts/share"; import { analyzedScratch, editableCodebase, identifierAt, scratchPath } from "#codebase/tcmts/studio"; import type { Node as ts_Node } from "typescript/ast"; import { SymbolFlags as ts_SymbolFlags } from "typescript/sync"; export async function definitionInScratch( file: string, text: string, offset: number, ): Promise<{ href?: string; at?: number } | null> { const cb = editableCodebase(); const abs = scratchPath(cb, file); const a = analyzedScratch(cb, abs, text); const id = identifierAt(a, abs, offset); if (!id) return null; const checker = a.checker; let sym = checker.getSymbolAtLocation(id); if (sym && sym.flags & ts_SymbolFlags.Alias) sym = checker.getAliasedSymbol(sym); if (!sym) return null; const hash = cacheRefOf(checker)(sym); if (hash) { const name = cb.store.pathsOf(cb.store.patched(hash))[0]; return name ? { href: codeHref(name) } : null; } const decl = declarationOf(sym); const sf = decl?.getSourceFile(); if (!decl || !sf || sf.fileName !== a.program.getSourceFile(abs)?.fileName) return null; const named = (decl as ts_Node & { name?: ts_Node }).name ?? decl; return { at: named.getStart(sf) }; }
uses
- tcmts.core.shape.cacheRefOf
- tcmts.core.ts.declarationOf
- tcmts.share.codeHref
- tcmts.studio.analyzedScratch
- tcmts.studio.editableCodebase
- tcmts.studio.identifierAt
- tcmts.studio.scratchPath