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
7 changes: 7 additions & 0 deletions snapshots/input/multi-project/packages/a/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@
export function a(): string {
return ''
}

export function localResult() {
interface LocalResult {
value: string
}
return { value: '' } as LocalResult
}
3 changes: 2 additions & 1 deletion snapshots/input/multi-project/packages/b/src/b.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { a } from '@example/a/src'
import { a, localResult } from '@example/a/src'

export function b() {
localResult().value
return a()
}
21 changes: 21 additions & 0 deletions snapshots/output/multi-project/packages/a/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,24 @@ export function a(): string {
return ''
}

export function localResult() {
// ^^^^^^^^^^^ definition @example/a 1.0.0 src/`index.ts`/localResult().
// documentation ```ts
// > function localResult(): LocalResult
// > ```
interface LocalResult {
// ^^^^^^^^^^^ definition local 0
// documentation ```ts
// > interface LocalResult
// > ```
value: string
// ^^^^^ definition local 1
// documentation ```ts
// > (property) value: string
// > ```
}
return { value: '' } as LocalResult
// ^^^^^ reference local 1
// ^^^^^^^^^^^ reference local 0
}

7 changes: 5 additions & 2 deletions snapshots/output/multi-project/packages/b/src/b.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// language TypeScript
// < definition @example/b 1.0.0 src/`b.ts`/

import { a } from '@example/a/src'
import { a, localResult } from '@example/a/src'
// ^ reference @example/a 1.0.0 src/`index.ts`/a().
// ^^^^^^^^^^^^^^^^ reference @example/a 1.0.0 src/`index.ts`/
// ^^^^^^^^^^^ reference @example/a 1.0.0 src/`index.ts`/localResult().
// ^^^^^^^^^^^^^^^^ reference @example/a 1.0.0 src/`index.ts`/

export function b() {
// ^ definition @example/b 1.0.0 src/`b.ts`/b().
localResult().value
//^^^^^^^^^^^ reference @example/a 1.0.0 src/`index.ts`/localResult().
return a()
// ^ reference @example/a 1.0.0 src/`index.ts`/a().
}
Expand Down
28 changes: 28 additions & 0 deletions src/FileIndexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,34 @@ export class FileIndexer {

this.emitSourceFileOccurrence()
this.visit(this.sourceFile)
const missingLocalDefinition = this.document.occurrences.find(
occurrence =>
occurrence.symbol.startsWith('local ') &&
(occurrence.symbol_roles & scip.scip.SymbolRole.Definition) !== 0 &&
!this.symbolInformation.has(occurrence.symbol)
)
if (missingLocalDefinition) {
throw new Error(
`local definition '${missingLocalDefinition.symbol}' has no SymbolInformation in '${this.document.relative_path}'`
)
}
// A SCIP local symbol is owned by one document. TypeScript can report
// synthetic or cross-file declaration candidates that the symbol algorithm
// cannot represent as locals in this document, so discard those unusable
// occurrences instead of emitting dangling local identities.
this.document.occurrences = this.document.occurrences.filter(
occurrence =>
!occurrence.symbol.startsWith('local ') ||
this.symbolInformation.has(occurrence.symbol)
)
// Relationships to locals have the same document-local ownership rule.
for (const symbol of this.document.symbols) {
symbol.relationships = symbol.relationships.filter(
relationship =>
!relationship.symbol.startsWith('local ') ||
this.symbolInformation.has(relationship.symbol)
)
}
}
private emitSourceFileOccurrence(): void {
const symbol = this.scipSymbol(this.sourceFile)
Expand Down
12 changes: 7 additions & 5 deletions src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,22 +145,24 @@ for (const snapshotDirectory of snapshotDirectories) {
.filter(
symbol =>
symbol &&
!symbol.startsWith('local ') &&
!availableSymbols.has(symbol)
(symbol.startsWith('local ')
? !symbols.has(symbol)
: !availableSymbols.has(symbol))
)
assert.equal(
missingOccurrenceSymbols,
[],
`${document.relative_path} global occurrences should have SymbolInformation`
`${document.relative_path} occurrences should have SymbolInformation`
)
const missingRelationshipSymbols = document.symbols
.flatMap(symbol => symbol.relationships)
.map(relationship => relationship.symbol)
.filter(
symbol =>
symbol &&
!symbol.startsWith('local ') &&
!availableSymbols.has(symbol)
(symbol.startsWith('local ')
? !symbols.has(symbol)
: !availableSymbols.has(symbol))
)
assert.equal(
missingRelationshipSymbols,
Expand Down
Loading