Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions snapshots/input/syntax/src/overload.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// format-options: showDocs

export interface Overloader {
onLiteral(param: 'a'): void
onLiteral(param: 'b'): void
Expand Down
20 changes: 20 additions & 0 deletions snapshots/output/syntax/src/overload.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
// language TypeScript
// < definition syntax 1.0.0 src/`overload.d.ts`/
//documentation ```ts
// > module "overload.d.ts"
// > ```

// format-options: showDocs

export interface Overloader {
// ^^^^^^^^^^ definition syntax 1.0.0 src/`overload.d.ts`/Overloader#
// documentation ```ts
// > interface Overloader
// > ```
onLiteral(param: 'a'): void
//^^^^^^^^^ definition syntax 1.0.0 src/`overload.d.ts`/Overloader#onLiteral().
//documentation ```ts
// > (method) onLiteral(param: "a"): void
// > ```
//documentation ```ts
// > (method) onLiteral(param: "b"): void
// > ```
// ^^^^^ definition syntax 1.0.0 src/`overload.d.ts`/Overloader#onLiteral().(param)
// documentation ```ts
// > (parameter) param: "a"
// > ```
// documentation ```ts
// > (parameter) param: "b"
// > ```
onLiteral(param: 'b'): void
//^^^^^^^^^ definition syntax 1.0.0 src/`overload.d.ts`/Overloader#onLiteral().
// ^^^^^ definition syntax 1.0.0 src/`overload.d.ts`/Overloader#onLiteral().(param)
Expand Down
63 changes: 49 additions & 14 deletions src/FileIndexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export class FileIndexer {
private localCounter = new Counter()
private propertyCounters: Map<string, Counter> = new Map()
private localSymbolTable: Map<ts.Node, ScipSymbol> = new Map()
private symbolInformation: Map<string, scip.scip.SymbolInformation> =
new Map()
private workingDirectoryRegExp: RegExp
constructor(
public readonly checker: ts.TypeChecker,
Expand Down Expand Up @@ -78,7 +80,7 @@ export class FileIndexer {
)
const moduleName =
this.sourceFile.moduleName || path.basename(this.sourceFile.fileName)
this.document.symbols.push(
this.pushSymbolInformation(
new scip.scip.SymbolInformation({
symbol: symbol.value,
documentation: ['```ts\nmodule "' + moduleName + '"\n```'],
Expand Down Expand Up @@ -344,15 +346,17 @@ export class FileIndexer {
): void {
const documentation = [
'```ts\n' +
this.hideWorkingDirectory(this.signatureForDocumentation(node, sym)) +
this.hideWorkingDirectory(
this.signatureForDocumentation(node, sym, declaration)
) +
'\n```',
]
const docstring = sym.getDocumentationComment(this.checker)
if (docstring.length > 0) {
documentation.push(ts.displayPartsToString(docstring))
}

this.document.symbols.push(
this.pushSymbolInformation(
new scip.scip.SymbolInformation({
symbol: symbol.value,
documentation,
Expand All @@ -362,6 +366,37 @@ export class FileIndexer {
)
}

private pushSymbolInformation(info: scip.scip.SymbolInformation): void {
const existing = this.symbolInformation.get(info.symbol)
if (!existing) {
this.symbolInformation.set(info.symbol, info)
this.document.symbols.push(info)
return
}

// Overload declarations share one SCIP symbol but can contribute distinct
// signatures and relationships. SCIP permits only one SymbolInformation
// entry per symbol, so merge that metadata into the first entry.
for (const documentation of info.documentation) {
if (!existing.documentation.includes(documentation)) {
existing.documentation.push(documentation)
}
}
for (const relationship of info.relationships) {
const previous = existing.relationships.find(
candidate => candidate.symbol === relationship.symbol
)
if (previous) {
previous.is_definition ||= relationship.is_definition
previous.is_reference ||= relationship.is_reference
previous.is_implementation ||= relationship.is_implementation
previous.is_type_definition ||= relationship.is_type_definition
} else {
existing.relationships.push(relationship)
}
}
}

private pushOccurrence(occurrence: scip.scip.Occurrence): void {
const lastOccurrence = this.document.occurrences.at(-1)
if (lastOccurrence) {
Expand Down Expand Up @@ -634,28 +669,28 @@ export class FileIndexer {
return undefined
}

private signatureForDocumentation(node: ts.Node, sym: ts.Symbol): string {
private signatureForDocumentation(
node: ts.Node,
sym: ts.Symbol,
declaration: ts.Node
): string {
const kind = scriptElementKind(node, sym)
const type = (): string =>
this.checker.typeToString(this.checker.getTypeAtLocation(node))
const asSignatureDeclaration = (
node: ts.Node,
sym: ts.Symbol
declaration: ts.Node
): ts.SignatureDeclaration | undefined => {
const declaration = sym.declarations?.[0]
if (!declaration) {
return undefined
}
return ts.isConstructorDeclaration(node)
? node
: ts.isFunctionDeclaration(declaration)
: ts.isFunctionDeclaration(declaration) ||
ts.isMethodDeclaration(declaration) ||
ts.isMethodSignature(declaration)
? declaration
: ts.isMethodDeclaration(declaration)
? declaration
: undefined
: undefined
}
const signature = (): string | undefined => {
const signatureDeclaration = asSignatureDeclaration(node, sym)
const signatureDeclaration = asSignatureDeclaration(node, declaration)
if (!signatureDeclaration) {
return undefined
}
Expand Down
13 changes: 13 additions & 0 deletions src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ for (const snapshotDirectory of snapshotDirectories) {
throw new Error('empty LSIF index')
}
for (const document of index.documents) {
const symbols = new Set<string>()
const duplicateSymbols: string[] = []
for (const symbol of document.symbols) {
if (symbols.has(symbol.symbol)) {
duplicateSymbols.push(symbol.symbol)
}
symbols.add(symbol.symbol)
}
assert.equal(
duplicateSymbols,
[],
`${document.relative_path} should not contain duplicate SymbolInformation`
)
assert.ok(
document.language,
`${document.relative_path} should have a SCIP document language`
Expand Down
Loading