Skip to content

Commit 0fd13db

Browse files
committed
Emit information for inferred object properties
Amp-Thread-ID: https://ampcode.com/threads/T-01a029e2-5095-710a-9cce-0c6d8645c173
1 parent 8426cba commit 0fd13db

4 files changed

Lines changed: 34 additions & 3 deletions

File tree

snapshots/output/syntax/src/object-literals-arrow-function.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function genericArrow2(): Foobar[] {
8383
return [1].map(n => ({ foobar: n + 1 }))
8484
// ^^^ reference typescript 6.0.3 lib/`lib.es5.d.ts`/Array#map().
8585
// ^ definition local 26
86-
// ^^^^^^ reference syntax 1.0.0 src/`object-literals-arrow-function.ts`/foobar1:
86+
// ^^^^^^ definition syntax 1.0.0 src/`object-literals-arrow-function.ts`/foobar1:
8787
// ^ reference local 26
8888
}
8989

snapshots/output/syntax/src/structural-type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function foo(): Promise<{ member: number }> {
1414
// ^^^^^^^ reference typescript 6.0.3 lib/`lib.es2015.promise.d.ts`/Promise.
1515
// ^^^^^^^ reference typescript 6.0.3 lib/`lib.es2015.symbol.wellknown.d.ts`/Promise#
1616
// ^^^^^^^ reference typescript 6.0.3 lib/`lib.es2015.promise.d.ts`/PromiseConstructor#resolve().
17-
// ^^^^^^ reference syntax 1.0.0 src/`structural-type.ts`/member0:
17+
// ^^^^^^ definition syntax 1.0.0 src/`structural-type.ts`/member0:
1818
}
1919
export function bar(): Promise<number> {
2020
// ^^^ definition syntax 1.0.0 src/`structural-type.ts`/bar().

src/FileIndexer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,11 @@ export class FileIndexer {
166166
objectElement,
167167
contextualType
168168
)
169-
return symbol?.getDeclarations()
169+
const declarations = symbol?.getDeclarations()
170+
// Inferred object types can contextually resolve a property back to its
171+
// own declaration. Treat that circular result as a definition instead of
172+
// emitting a reference to a symbol that never gets SymbolInformation.
173+
return declarations?.includes(objectElement) ? undefined : declarations
170174
}
171175

172176
private visitSymbolOccurrence(node: ts.Node, sym: ts.Symbol): void {

src/main.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ for (const snapshotDirectory of snapshotDirectories) {
8383
documentPaths.add(document.relative_path)
8484
}
8585
assert.equal(duplicateDocuments, [], 'SCIP document paths should be unique')
86+
const symbolInformation = new Set(
87+
index.documents.flatMap(document =>
88+
document.symbols.map(symbol => symbol.symbol)
89+
)
90+
)
91+
const indexedPackages = new Set(
92+
[...symbolInformation]
93+
.filter(symbol => !symbol.startsWith('local '))
94+
.map(symbolPackage)
95+
)
8696
for (const document of index.documents) {
8797
const symbols = new Set<string>()
8898
const duplicateSymbols: string[] = []
@@ -111,6 +121,19 @@ for (const snapshotDirectory of snapshotDirectories) {
111121
[],
112122
`${document.relative_path} should not contain duplicate occurrences`
113123
)
124+
const missingInternalSymbols = document.occurrences
125+
.map(occurrence => occurrence.symbol)
126+
.filter(
127+
symbol =>
128+
symbol &&
129+
indexedPackages.has(symbolPackage(symbol)) &&
130+
!symbolInformation.has(symbol)
131+
)
132+
assert.equal(
133+
missingInternalSymbols,
134+
[],
135+
`${document.relative_path} occurrences in indexed packages should have SymbolInformation`
136+
)
114137
assert.ok(
115138
document.language,
116139
`${document.relative_path} should have a SCIP document language`
@@ -162,4 +185,8 @@ for (const snapshotDirectory of snapshotDirectories) {
162185
})
163186
}
164187

188+
function symbolPackage(symbol: string): string {
189+
return symbol.split(' ', 4).join(' ')
190+
}
191+
165192
test.run()

0 commit comments

Comments
 (0)