@@ -230,10 +230,8 @@ export class DeclarationReferenceGenerator {
230
230
if ( ! includeModuleSymbols ) {
231
231
return undefined ;
232
232
}
233
- const sourceFile : ts . SourceFile | undefined =
234
- followedSymbol . declarations &&
235
- followedSymbol . declarations [ 0 ] &&
236
- followedSymbol . declarations [ 0 ] . getSourceFile ( ) ;
233
+ const declaration : ts . Node | undefined = TypeScriptHelpers . tryGetADeclaration ( symbol ) ;
234
+ const sourceFile : ts . SourceFile | undefined = declaration ?. getSourceFile ( ) ;
237
235
return new DeclarationReference ( this . _sourceFileToModuleSource ( sourceFile ) ) ;
238
236
}
239
237
@@ -242,28 +240,8 @@ export class DeclarationReferenceGenerator {
242
240
return undefined ;
243
241
}
244
242
245
- const parent : ts . Symbol | undefined = TypeScriptInternals . getSymbolParent ( followedSymbol ) ;
246
- let parentRef : DeclarationReference | undefined ;
247
- if ( parent ) {
248
- parentRef = this . _symbolToDeclarationReference (
249
- parent ,
250
- ts . SymbolFlags . Namespace ,
251
- /*includeModuleSymbols*/ true
252
- ) ;
253
- } else {
254
- // this may be a local symbol in a module...
255
- const sourceFile : ts . SourceFile | undefined =
256
- followedSymbol . declarations &&
257
- followedSymbol . declarations [ 0 ] &&
258
- followedSymbol . declarations [ 0 ] . getSourceFile ( ) ;
259
- if ( sourceFile && ts . isExternalModule ( sourceFile ) ) {
260
- parentRef = new DeclarationReference ( this . _sourceFileToModuleSource ( sourceFile ) ) ;
261
- } else {
262
- parentRef = new DeclarationReference ( GlobalSource . instance ) ;
263
- }
264
- }
265
-
266
- if ( parentRef === undefined ) {
243
+ let parentRef : DeclarationReference | undefined = this . _getParentReference ( followedSymbol ) ;
244
+ if ( ! parentRef ) {
267
245
return undefined ;
268
246
}
269
247
@@ -306,6 +284,55 @@ export class DeclarationReferenceGenerator {
306
284
. withMeaning ( DeclarationReferenceGenerator . _getMeaningOfSymbol ( followedSymbol , meaning ) ) ;
307
285
}
308
286
287
+ private _getParentReference ( symbol : ts . Symbol ) : DeclarationReference | undefined {
288
+ const declaration : ts . Node | undefined = TypeScriptHelpers . tryGetADeclaration ( symbol ) ;
289
+
290
+ // First, try to find a parent symbol via the symbol tree.
291
+ const parentSymbol : ts . Symbol | undefined = TypeScriptInternals . getSymbolParent ( symbol ) ;
292
+ if ( parentSymbol ) {
293
+ return this . _symbolToDeclarationReference (
294
+ parentSymbol ,
295
+ parentSymbol . flags ,
296
+ /*includeModuleSymbols*/ true
297
+ ) ;
298
+ }
299
+
300
+ // If that doesn't work, try to find a parent symbol via the node tree. As far as we can tell,
301
+ // this logic is only needed for local symbols within namespaces. For example:
302
+ //
303
+ // ```
304
+ // export namespace n {
305
+ // type SomeType = number;
306
+ // export function someFunction(): SomeType { return 5; }
307
+ // }
308
+ // ```
309
+ //
310
+ // In the example above, `SomeType` doesn't have a parent symbol per the TS internal API above,
311
+ // but its reference still needs to be qualified with the parent reference for `n`.
312
+ const grandParent : ts . Node | undefined = declaration ?. parent ?. parent ;
313
+ if ( grandParent && ts . isModuleDeclaration ( grandParent ) ) {
314
+ const grandParentSymbol : ts . Symbol | undefined = TypeScriptInternals . tryGetSymbolForDeclaration (
315
+ grandParent ,
316
+ this . _typeChecker
317
+ ) ;
318
+ if ( grandParentSymbol ) {
319
+ return this . _symbolToDeclarationReference (
320
+ grandParentSymbol ,
321
+ grandParentSymbol . flags ,
322
+ /*includeModuleSymbols*/ true
323
+ ) ;
324
+ }
325
+ }
326
+
327
+ // At this point, we have a local symbol in a module.
328
+ const sourceFile : ts . SourceFile | undefined = declaration ?. getSourceFile ( ) ;
329
+ if ( sourceFile && ts . isExternalModule ( sourceFile ) ) {
330
+ return new DeclarationReference ( this . _sourceFileToModuleSource ( sourceFile ) ) ;
331
+ } else {
332
+ return new DeclarationReference ( GlobalSource . instance ) ;
333
+ }
334
+ }
335
+
309
336
private _getPackageName ( sourceFile : ts . SourceFile ) : string {
310
337
if ( this . _program . isSourceFileFromExternalLibrary ( sourceFile ) ) {
311
338
const packageJson : INodePackageJson | undefined = this . _packageJsonLookup . tryLoadNodePackageJsonFor (
0 commit comments