@sourcefield/lsif-typescript
Version:
LSIF indexer for TypeScript and JavaScript
90 lines (86 loc) • 2.88 kB
text/typescript
import { Input } from './Input'
import * as lsif from './lsif'
import { Range } from './Range'
const lsiftyped = lsif.lib.codeintel.lsiftyped
export function formatSnapshot(
input: Input,
document: lsif.lib.codeintel.lsiftyped.Document
): string {
const out: string[] = []
document.occurrences.sort(occurrencesByLine)
const symbolTable = new Map<
string,
lsif.lib.codeintel.lsiftyped.SymbolInformation
>()
for (const symbolInfo of document.symbols) {
symbolTable.set(symbolInfo.symbol, symbolInfo)
}
let occurrenceIndex = 0
for (const [lineNumber, line] of input.lines.entries()) {
out.push(' ')
out.push(line)
out.push('\n')
while (
occurrenceIndex < document.occurrences.length &&
document.occurrences[occurrenceIndex].range[0] === lineNumber
) {
const occurrence = document.occurrences[occurrenceIndex]
occurrenceIndex++
if (occurrence.range.length > 3) {
// Skip multiline occurrences for now.
continue
}
const range = Range.fromLsif(occurrence.range)
out.push('//')
out.push(' '.repeat(range.start.character))
const length = range.end.character - range.start.character
if (length < 0) {
throw new Error(input.format(range, 'negative length occurrence!'))
}
out.push('^'.repeat(length))
out.push(' ')
const isDefinition =
(occurrence.symbol_roles & lsiftyped.SymbolRole.Definition) > 0
out.push(isDefinition ? 'definition' : 'reference')
out.push(' ')
const symbol = occurrence.symbol.startsWith('lsif-typescript npm ')
? occurrence.symbol.slice('lsif-typescript npm '.length)
: occurrence.symbol
out.push(symbol)
const info = symbolTable.get(occurrence.symbol)
if (!isDefinition || !info) {
out.push('\n')
continue
}
const prefix = '\n//' + ' '.repeat(range.start.character)
for (const documentation of info.documentation) {
out.push(prefix)
out.push('documentation ')
out.push(documentation.replace(/\n/g, '\\n'))
}
info.relationships.sort((a, b) => a.symbol.localeCompare(b.symbol))
for (const relationship of info.relationships) {
out.push(prefix)
out.push('relationship')
if (relationship.is_implementation) {
out.push(' implementation')
}
if (relationship.is_reference) {
out.push(' reference')
}
if (relationship.is_type_definition) {
out.push(' type_definition')
}
out.push(' ' + relationship.symbol)
}
out.push('\n')
}
}
return out.join('')
}
function occurrencesByLine(
a: lsif.lib.codeintel.lsiftyped.Occurrence,
b: lsif.lib.codeintel.lsiftyped.Occurrence
): number {
return Range.fromLsif(a.range).compare(Range.fromLsif(b.range))
}