typedoc 0.25.2 → 0.25.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/lib/application.js +9 -2
  2. package/dist/lib/converter/comments/declarationReference.js +14 -14
  3. package/dist/lib/converter/comments/discovery.js +3 -1
  4. package/dist/lib/converter/comments/parser.js +56 -13
  5. package/dist/lib/converter/factories/index-signature.js +1 -0
  6. package/dist/lib/converter/plugins/TypePlugin.js +4 -1
  7. package/dist/lib/converter/symbols.js +24 -14
  8. package/dist/lib/converter/types.js +15 -13
  9. package/dist/lib/converter/utils/repository.js +4 -4
  10. package/dist/lib/converter/utils/symbols.js +5 -0
  11. package/dist/lib/models/reflections/ReflectionSymbolId.d.ts +9 -0
  12. package/dist/lib/models/reflections/ReflectionSymbolId.js +28 -11
  13. package/dist/lib/models/reflections/abstract.js +257 -200
  14. package/dist/lib/models/types.js +21 -21
  15. package/dist/lib/output/themes/MarkedPlugin.js +16 -9
  16. package/dist/lib/output/themes/default/DefaultThemeRenderContext.d.ts +14 -3
  17. package/dist/lib/output/themes/default/DefaultThemeRenderContext.js +10 -0
  18. package/dist/lib/output/themes/default/partials/comment.js +8 -3
  19. package/dist/lib/output/themes/default/partials/footer.js +1 -1
  20. package/dist/lib/output/themes/default/partials/member.signatures.js +2 -1
  21. package/dist/lib/output/themes/default/partials/member.sources.js +25 -11
  22. package/dist/lib/output/themes/default/partials/reflectionPreview.d.ts +4 -0
  23. package/dist/lib/output/themes/default/partials/reflectionPreview.js +21 -0
  24. package/dist/lib/output/themes/default/partials/type.d.ts +3 -1
  25. package/dist/lib/output/themes/default/partials/type.js +27 -24
  26. package/dist/lib/output/themes/default/templates/reflection.js +2 -1
  27. package/dist/lib/utils/general.d.ts +1 -0
  28. package/dist/lib/utils/general.js +11 -1
  29. package/dist/lib/utils/jsx.js +4 -3
  30. package/dist/lib/utils/options/declaration.d.ts +1 -0
  31. package/dist/lib/utils/options/declaration.js +2 -2
  32. package/dist/lib/utils/options/options.js +6 -5
  33. package/dist/lib/utils/options/sources/typedoc.js +20 -15
  34. package/dist/lib/utils/sort.d.ts +1 -1
  35. package/dist/lib/utils/sort.js +4 -0
  36. package/package.json +6 -4
  37. package/static/style.css +11 -0
@@ -96,6 +96,7 @@ const application_events_1 = require("./application-events");
96
96
  const tsconfig_1 = require("./utils/tsconfig");
97
97
  const fs_1 = require("./utils/fs");
98
98
  const abstract_1 = require("./models/reflections/abstract");
99
+ const ReflectionSymbolId_1 = require("./models/reflections/ReflectionSymbolId");
99
100
  // eslint-disable-next-line @typescript-eslint/no-var-requires
100
101
  const packageInfo = require("../../package.json");
101
102
  const supportedVersionMajorMinor = packageInfo.peerDependencies.typescript
@@ -451,9 +452,10 @@ let Application = (() => {
451
452
  }
452
453
  const origOptions = this.options;
453
454
  const projects = [];
455
+ const projectsToConvert = [];
454
456
  // Generate a json file for each package
455
457
  for (const dir of packageDirs) {
456
- this.logger.info(`Converting project at ${(0, paths_1.nicePath)(dir)}`);
458
+ this.logger.verbose(`Reading project at ${(0, paths_1.nicePath)(dir)}`);
457
459
  const opts = origOptions.copyForPackage(dir);
458
460
  await opts.read(this.logger, dir);
459
461
  // Invalid links should only be reported after everything has been merged.
@@ -463,7 +465,12 @@ let Application = (() => {
463
465
  this.logger.error(`Project at ${(0, paths_1.nicePath)(dir)} has entryPointStrategy set to packages, but nested packages are not supported.`);
464
466
  continue;
465
467
  }
466
- this.options = opts;
468
+ (0, ReflectionSymbolId_1.addInferredDeclarationMapPaths)(opts.getCompilerOptions(), opts.getFileNames());
469
+ projectsToConvert.push({ dir, options: opts });
470
+ }
471
+ for (const { dir, options } of projectsToConvert) {
472
+ this.logger.info(`Converting project at ${(0, paths_1.nicePath)(dir)}`);
473
+ this.options = options;
467
474
  const project = await this.convert();
468
475
  if (project) {
469
476
  this.validate(project);
@@ -9,20 +9,20 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.parseDeclarationReference = exports.parseMeaning = exports.parseComponentPath = exports.parseComponent = exports.parseSymbolReference = exports.parseModuleSource = exports.parseString = exports.MeaningKeywords = void 0;
11
11
  exports.MeaningKeywords = [
12
- "class",
13
- "interface",
14
- "type",
15
- "enum",
16
- "namespace",
17
- "function",
18
- "var",
19
- "constructor",
20
- "member",
21
- "event",
22
- "call",
23
- "new",
24
- "index",
25
- "complex",
12
+ "class", // SymbolFlags.Class
13
+ "interface", // SymbolFlags.Interface
14
+ "type", // SymbolFlags.TypeAlias
15
+ "enum", // SymbolFlags.Enum
16
+ "namespace", // SymbolFlags.Module
17
+ "function", // SymbolFlags.Function
18
+ "var", // SymbolFlags.Variable
19
+ "constructor", // SymbolFlags.Constructor
20
+ "member", // SymbolFlags.ClassMember | SymbolFlags.EnumMember
21
+ "event", //
22
+ "call", // SymbolFlags.Signature (for __call)
23
+ "new", // SymbolFlags.Signature (for __new)
24
+ "index", // SymbolFlags.Signature (for __index)
25
+ "complex", // Any complex type
26
26
  // TypeDoc specific
27
27
  "getter",
28
28
  "setter",
@@ -121,13 +121,15 @@ function discoverComment(symbol, kind, logger, commentStyle) {
121
121
  // not the last one, since that will apply to the import or declaration.
122
122
  const reverse = !symbol.declarations?.some(typescript_1.default.isSourceFile);
123
123
  const discovered = [];
124
+ const seen = new Set();
124
125
  for (const decl of symbol.declarations || []) {
125
126
  const text = decl.getSourceFile().text;
126
127
  if (wantedKinds[kind].includes(decl.kind)) {
127
128
  const node = declarationToCommentNode(decl);
128
- if (!node) {
129
+ if (!node || seen.has(node)) {
129
130
  continue;
130
131
  }
132
+ seen.add(node);
131
133
  // Special behavior here! We temporarily put the implementation comment
132
134
  // on the reflection which contains all the signatures. This lets us pull
133
135
  // the comment on the implementation if some signature does not have a comment.
@@ -126,8 +126,8 @@ function blockTag(comment, lexer, config, warning) {
126
126
  (0, assert_1.ok)(blockTag.kind === lexer_1.TokenSyntaxKind.Tag, "blockTag called not at the start of a block tag."); // blockContent is broken if this fails.
127
127
  const tagName = aliasedTags.get(blockTag.text) || blockTag.text;
128
128
  let content;
129
- if (tagName === "@example" && config.jsDocCompatibility.exampleTag) {
130
- content = exampleBlockContent(comment, lexer, config, warning);
129
+ if (tagName === "@example") {
130
+ return exampleBlock(comment, lexer, config, warning);
131
131
  }
132
132
  else if (["@default", "@defaultValue"].includes(tagName) &&
133
133
  config.jsDocCompatibility.defaultTag) {
@@ -168,14 +168,59 @@ function defaultBlockContent(comment, lexer, config, warning) {
168
168
  /**
169
169
  * The `@example` tag gets a special case because otherwise we will produce many warnings
170
170
  * about unescaped/mismatched/missing braces in legacy JSDoc comments.
171
+ *
172
+ * In TSDoc, we also want to treat the first line of the block as the example name.
171
173
  */
172
- function exampleBlockContent(comment, lexer, config, warning) {
174
+ function exampleBlock(comment, lexer, config, warning) {
173
175
  lexer.mark();
174
176
  const content = blockContent(comment, lexer, config, () => { });
175
177
  const end = lexer.done() || lexer.peek();
176
178
  lexer.release();
177
- if (content.some((part) => part.kind === "code" && part.text.startsWith("```"))) {
178
- return blockContent(comment, lexer, config, warning);
179
+ if (!config.jsDocCompatibility.exampleTag ||
180
+ content.some((part) => part.kind === "code" && part.text.startsWith("```"))) {
181
+ let exampleName = "";
182
+ // First line of @example block is the example name.
183
+ let warnedAboutRichNameContent = false;
184
+ outer: while ((lexer.done() || lexer.peek()) !== end) {
185
+ const next = lexer.peek();
186
+ switch (next.kind) {
187
+ case lexer_1.TokenSyntaxKind.NewLine:
188
+ lexer.take();
189
+ break outer;
190
+ case lexer_1.TokenSyntaxKind.Text: {
191
+ const newline = next.text.indexOf("\n");
192
+ if (newline !== -1) {
193
+ exampleName += next.text.substring(0, newline);
194
+ next.pos += newline + 1;
195
+ break outer;
196
+ }
197
+ else {
198
+ exampleName += lexer.take().text;
199
+ }
200
+ break;
201
+ }
202
+ case lexer_1.TokenSyntaxKind.Code:
203
+ case lexer_1.TokenSyntaxKind.Tag:
204
+ case lexer_1.TokenSyntaxKind.TypeAnnotation:
205
+ case lexer_1.TokenSyntaxKind.CloseBrace:
206
+ case lexer_1.TokenSyntaxKind.OpenBrace:
207
+ if (!warnedAboutRichNameContent) {
208
+ warning("The first line of an example tag will be taken literally as" +
209
+ " the example name, and should only contain text.", lexer.peek());
210
+ warnedAboutRichNameContent = true;
211
+ }
212
+ exampleName += lexer.take().text;
213
+ break;
214
+ default:
215
+ (0, utils_1.assertNever)(next.kind);
216
+ }
217
+ }
218
+ const content = blockContent(comment, lexer, config, warning);
219
+ const tag = new models_1.CommentTag("@example", content);
220
+ if (exampleName.trim()) {
221
+ tag.name = exampleName.trim();
222
+ }
223
+ return tag;
179
224
  }
180
225
  const tokens = [];
181
226
  while ((lexer.done() || lexer.peek()) !== end) {
@@ -187,24 +232,22 @@ function exampleBlockContent(comment, lexer, config, warning) {
187
232
  .trim();
188
233
  const caption = blockText.match(/^\s*<caption>(.*?)<\/caption>\s*(\n|$)/);
189
234
  if (caption) {
190
- return [
191
- {
192
- kind: "text",
193
- text: caption[1] + "\n",
194
- },
235
+ const tag = new models_1.CommentTag("@example", [
195
236
  {
196
237
  kind: "code",
197
238
  text: makeCodeBlock(blockText.slice(caption[0].length)),
198
239
  },
199
- ];
240
+ ]);
241
+ tag.name = caption[1];
242
+ return tag;
200
243
  }
201
244
  else {
202
- return [
245
+ return new models_1.CommentTag("@example", [
203
246
  {
204
247
  kind: "code",
205
248
  text: makeCodeBlock(blockText),
206
249
  },
207
- ];
250
+ ]);
208
251
  }
209
252
  }
210
253
  function blockContent(comment, lexer, config, warning) {
@@ -21,6 +21,7 @@ function convertIndexSignature(context, symbol) {
21
21
  const param = indexDeclaration.parameters[0];
22
22
  (0, assert_1.default)(param && typescript_1.default.isParameter(param));
23
23
  const index = new models_1.SignatureReflection("__index", models_1.ReflectionKind.IndexSignature, context.scope);
24
+ index.comment = context.getComment(indexSymbol, index.kind);
24
25
  index.parameters = [
25
26
  new models_1.ParameterReflection(param.name.getText(), models_1.ReflectionKind.Parameter, index),
26
27
  ];
@@ -156,7 +156,10 @@ let TypePlugin = (() => {
156
156
  if (reflection.extendedBy) {
157
157
  push(reflection.extendedBy);
158
158
  }
159
- reflection.typeHierarchy = root;
159
+ // No point setting up a hierarchy if there is no hierarchy to display
160
+ if (root.next) {
161
+ reflection.typeHierarchy = root;
162
+ }
160
163
  });
161
164
  }
162
165
  };
@@ -110,15 +110,6 @@ function convertSymbol(context, symbol, exportSymbol) {
110
110
  // { methodProperty() {} }
111
111
  flags = (0, enum_1.removeFlag)(flags, typescript_1.default.SymbolFlags.Property);
112
112
  }
113
- // A default exported function with no associated variable is a property, but
114
- // we should really convert it as a variable for documentation purposes
115
- // export default () => {}
116
- // export default 123
117
- if (flags === typescript_1.default.SymbolFlags.Property &&
118
- symbol.name === "default" &&
119
- context.scope.kindOf(models_1.ReflectionKind.Module | models_1.ReflectionKind.Project)) {
120
- flags = typescript_1.default.SymbolFlags.BlockScopedVariable;
121
- }
122
113
  for (const flag of (0, enum_1.getEnumFlags)(flags ^ allConverterFlags)) {
123
114
  if (!(flag & allConverterFlags)) {
124
115
  context.logger.verbose(`Missing converter for symbol: ${symbol.name} with flag ${typescript_1.default.SymbolFlags[flag]}`);
@@ -359,8 +350,15 @@ function convertClassOrInterface(context, symbol, exportSymbol) {
359
350
  convertConstructSignatures(reflectionContext, symbol);
360
351
  // And finally, index signatures
361
352
  (0, index_signature_1.convertIndexSignature)(reflectionContext, symbol);
353
+ // Normally this shouldn't matter, unless someone did something with skipLibCheck off.
354
+ return typescript_1.default.SymbolFlags.Alias;
362
355
  }
363
356
  function convertProperty(context, symbol, exportSymbol) {
357
+ // This might happen if we're converting a function-module created with Object.assign
358
+ // or `export default () => {}`
359
+ if (context.scope.kindOf(models_1.ReflectionKind.SomeModule | models_1.ReflectionKind.Project)) {
360
+ return convertVariable(context, symbol, exportSymbol);
361
+ }
364
362
  const declarations = symbol.getDeclarations() ?? [];
365
363
  // Don't do anything if we inherited this property and it is private.
366
364
  if (isInherited(context, symbol) &&
@@ -466,9 +464,10 @@ function createAlias(target, context, symbol, exportSymbol) {
466
464
  }
467
465
  function convertVariable(context, symbol, exportSymbol) {
468
466
  const declaration = symbol.getDeclarations()?.[0];
469
- (0, assert_1.default)(declaration);
470
467
  const comment = context.getComment(symbol, models_1.ReflectionKind.Variable);
471
- const type = context.checker.getTypeOfSymbolAtLocation(symbol, declaration);
468
+ const type = declaration
469
+ ? context.checker.getTypeOfSymbolAtLocation(symbol, declaration)
470
+ : context.checker.getTypeOfSymbol(symbol);
472
471
  if (isEnumLike(context.checker, type, declaration) &&
473
472
  comment?.hasModifier("@enum")) {
474
473
  return convertVariableAsEnum(context, symbol, exportSymbol);
@@ -481,7 +480,7 @@ function convertVariable(context, symbol, exportSymbol) {
481
480
  }
482
481
  const reflection = context.createDeclarationReflection(models_1.ReflectionKind.Variable, symbol, exportSymbol);
483
482
  let typeNode;
484
- if (typescript_1.default.isVariableDeclaration(declaration)) {
483
+ if (declaration && typescript_1.default.isVariableDeclaration(declaration)) {
485
484
  // Otherwise we might have destructuring
486
485
  typeNode = declaration.type;
487
486
  }
@@ -492,7 +491,7 @@ function convertVariable(context, symbol, exportSymbol) {
492
491
  return typescript_1.default.SymbolFlags.Property;
493
492
  }
494
493
  function isEnumLike(checker, type, location) {
495
- if (!(0, enum_1.hasAllFlags)(type.flags, typescript_1.default.TypeFlags.Object)) {
494
+ if (!location || !(0, enum_1.hasAllFlags)(type.flags, typescript_1.default.TypeFlags.Object)) {
496
495
  return false;
497
496
  }
498
497
  return type.getProperties().every((prop) => {
@@ -545,6 +544,14 @@ function convertVariableAsFunction(context, symbol, exportSymbol) {
545
544
  for (const signature of type.getCallSignatures()) {
546
545
  (0, signature_1.createSignature)(reflectionContext, models_1.ReflectionKind.CallSignature, signature, symbol);
547
546
  }
547
+ // #2436: Functions created with Object.assign on a function won't have a namespace flag
548
+ // but likely have properties that we should put into a namespace.
549
+ if (type.getProperties().length &&
550
+ !(0, enum_1.hasAnyFlag)(symbol.flags, typescript_1.default.SymbolFlags.NamespaceModule | typescript_1.default.SymbolFlags.ValueModule)) {
551
+ const ns = context.createDeclarationReflection(models_1.ReflectionKind.Namespace, symbol, exportSymbol);
552
+ context.finalizeDeclarationReflection(ns);
553
+ convertSymbols(context.withScope(ns), type.getProperties());
554
+ }
548
555
  return typescript_1.default.SymbolFlags.Property;
549
556
  }
550
557
  function convertAccessor(context, symbol, exportSymbol) {
@@ -572,7 +579,10 @@ function convertAccessor(context, symbol, exportSymbol) {
572
579
  }
573
580
  function isInherited(context, symbol) {
574
581
  const parentSymbol = context.project.getSymbolFromReflection(context.scope);
575
- (0, assert_1.default)(parentSymbol, `No parent symbol found for ${symbol.name} in ${context.scope.name}`);
582
+ // It'd be nice to be able to assert that this is true, but sometimes object
583
+ // types don't get symbols if they are inferred.
584
+ if (!parentSymbol)
585
+ return false;
576
586
  const parents = parentSymbol.declarations?.slice() || [];
577
587
  const constructorDecls = parents.flatMap((parent) => typescript_1.default.isClassDeclaration(parent)
578
588
  ? parent.members.filter(typescript_1.default.isConstructorDeclaration)
@@ -164,13 +164,14 @@ const constructorConverter = {
164
164
  return new models_1.ReflectionType(reflection);
165
165
  },
166
166
  convertType(context, type) {
167
- if (!type.symbol) {
167
+ const symbol = type.getSymbol();
168
+ if (!symbol) {
168
169
  return new models_1.IntrinsicType("Function");
169
170
  }
170
171
  const reflection = new models_1.DeclarationReflection("__type", models_1.ReflectionKind.Constructor, context.scope);
171
- context.registerReflection(reflection, type.symbol);
172
+ context.registerReflection(reflection, symbol);
172
173
  context.trigger(converter_events_1.ConverterEvents.CREATE_DECLARATION, reflection);
173
- (0, signature_1.createSignature)(context.withScope(reflection), models_1.ReflectionKind.ConstructorSignature, type.getConstructSignatures()[0], type.symbol);
174
+ (0, signature_1.createSignature)(context.withScope(reflection), models_1.ReflectionKind.ConstructorSignature, type.getConstructSignatures()[0], symbol);
174
175
  return new models_1.ReflectionType(reflection);
175
176
  },
176
177
  };
@@ -212,11 +213,12 @@ const functionTypeConverter = {
212
213
  return new models_1.ReflectionType(reflection);
213
214
  },
214
215
  convertType(context, type) {
215
- if (!type.symbol) {
216
+ const symbol = type.getSymbol();
217
+ if (!symbol) {
216
218
  return new models_1.IntrinsicType("Function");
217
219
  }
218
220
  const reflection = new models_1.DeclarationReflection("__type", models_1.ReflectionKind.TypeLiteral, context.scope);
219
- context.registerReflection(reflection, type.symbol);
221
+ context.registerReflection(reflection, symbol);
220
222
  context.trigger(converter_events_1.ConverterEvents.CREATE_DECLARATION, reflection);
221
223
  (0, signature_1.createSignature)(context.withScope(reflection), models_1.ReflectionKind.CallSignature, type.getCallSignatures()[0], type.getSymbol());
222
224
  return new models_1.ReflectionType(reflection);
@@ -251,7 +253,7 @@ const inferredConverter = {
251
253
  return new models_1.InferredType(node.typeParameter.name.text, maybeConvertType(context, node.typeParameter.constraint));
252
254
  },
253
255
  convertType(context, type) {
254
- return new models_1.InferredType(type.symbol.name, maybeConvertType(context, type.getConstraint()));
256
+ return new models_1.InferredType(type.getSymbol().name, maybeConvertType(context, type.getConstraint()));
255
257
  },
256
258
  };
257
259
  const intersectionConverter = {
@@ -372,22 +374,22 @@ const typeLiteralConverter = {
372
374
  return new models_1.ReflectionType(reflection);
373
375
  },
374
376
  convertType(context, type) {
375
- if (!type.symbol) {
376
- return new models_1.IntrinsicType("Object");
377
- }
377
+ const symbol = type.getSymbol();
378
378
  const reflection = new models_1.DeclarationReflection("__type", models_1.ReflectionKind.TypeLiteral, context.scope);
379
- context.registerReflection(reflection, type.symbol);
379
+ context.registerReflection(reflection, symbol);
380
380
  context.trigger(converter_events_1.ConverterEvents.CREATE_DECLARATION, reflection);
381
381
  for (const prop of context.checker.getPropertiesOfType(type)) {
382
382
  (0, symbols_1.convertSymbol)(context.withScope(reflection), prop);
383
383
  }
384
384
  for (const signature of type.getCallSignatures()) {
385
- (0, signature_1.createSignature)(context.withScope(reflection), models_1.ReflectionKind.CallSignature, signature, type.symbol);
385
+ (0, signature_1.createSignature)(context.withScope(reflection), models_1.ReflectionKind.CallSignature, signature, symbol);
386
386
  }
387
387
  for (const signature of type.getConstructSignatures()) {
388
- (0, signature_1.createSignature)(context.withScope(reflection), models_1.ReflectionKind.ConstructorSignature, signature, type.symbol);
388
+ (0, signature_1.createSignature)(context.withScope(reflection), models_1.ReflectionKind.ConstructorSignature, signature, symbol);
389
+ }
390
+ if (symbol) {
391
+ (0, index_signature_1.convertIndexSignature)(context.withScope(reflection), symbol);
389
392
  }
390
- (0, index_signature_1.convertIndexSignature)(context.withScope(reflection), type.symbol);
391
393
  return new models_1.ReflectionType(reflection);
392
394
  },
393
395
  };
@@ -29,7 +29,7 @@ class AssumedRepository {
29
29
  path: fileName.substring(this.path.length + 1),
30
30
  line,
31
31
  };
32
- return this.sourceLinkTemplate.replace(/\{(path|line)\}/g, (_, key) => replacements[key]);
32
+ return this.sourceLinkTemplate.replace(/\{(gitRevision|path|line)\}/g, (_, key) => replacements[key]);
33
33
  }
34
34
  }
35
35
  exports.AssumedRepository = AssumedRepository;
@@ -117,9 +117,9 @@ exports.GitRepository = GitRepository;
117
117
  // 3. project
118
118
  const repoExpressions = [
119
119
  /(github(?!.us)(?:\.[a-z]+)*\.[a-z]{2,})[:/]([^/]+)\/(.*)/,
120
- /(\w+\.githubprivate.com)[:/]([^/]+)\/(.*)/,
121
- /(\w+\.ghe.com)[:/]([^/]+)\/(.*)/,
122
- /(\w+\.github.us)[:/]([^/]+)\/(.*)/,
120
+ /(\w+\.githubprivate.com)[:/]([^/]+)\/(.*)/, // GitHub enterprise
121
+ /(\w+\.ghe.com)[:/]([^/]+)\/(.*)/, // GitHub enterprise
122
+ /(\w+\.github.us)[:/]([^/]+)\/(.*)/, // GitHub enterprise
123
123
  /(bitbucket.org)[:/]([^/]+)\/(.*)/,
124
124
  /(gitlab.com)[:/]([^/]+)\/(.*)/,
125
125
  ];
@@ -6,8 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.resolveAliasedSymbol = void 0;
7
7
  const typescript_1 = __importDefault(require("typescript"));
8
8
  function resolveAliasedSymbol(symbol, checker) {
9
+ const seen = new Set();
9
10
  while (typescript_1.default.SymbolFlags.Alias & symbol.flags) {
10
11
  symbol = checker.getAliasedSymbol(symbol);
12
+ // #2438, with declaration files, we might have an aliased symbol which eventually points to itself.
13
+ if (seen.has(symbol))
14
+ return symbol;
15
+ seen.add(symbol);
11
16
  }
12
17
  return symbol;
13
18
  }
@@ -17,8 +17,16 @@ export declare class ReflectionSymbolId {
17
17
  /**
18
18
  * Note: This is **not** serialized. It exists for sorting by declaration order, but
19
19
  * should not be needed when deserializing from JSON.
20
+ * Will be set to `Infinity` if the ID was deserialized from JSON.
20
21
  */
21
22
  pos: number;
23
+ /**
24
+ * Note: This is **not** serialized. It exists to support detection of the differences between
25
+ * symbols which share declarations, but are instantiated with different type parameters.
26
+ * This will be `NaN` if the symbol reference is not transient.
27
+ * Note: This can only be non-NaN if {@link pos} is finite.
28
+ */
29
+ transientId: number;
22
30
  constructor(symbol: ts.Symbol, declaration?: ts.Declaration);
23
31
  constructor(json: JSONOutput.ReflectionSymbolId);
24
32
  getStableKey(): ReflectionSymbolIdString;
@@ -27,3 +35,4 @@ export declare class ReflectionSymbolId {
27
35
  qualifiedName: string;
28
36
  };
29
37
  }
38
+ export declare function addInferredDeclarationMapPaths(opts: ts.CompilerOptions, files: readonly string[]): void;
@@ -3,14 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ReflectionSymbolId = void 0;
6
+ exports.addInferredDeclarationMapPaths = exports.ReflectionSymbolId = void 0;
7
7
  const fs_1 = require("fs");
8
8
  const path_1 = require("path");
9
9
  const typescript_1 = __importDefault(require("typescript"));
10
10
  const fs_2 = require("../../utils/fs");
11
+ const paths_1 = require("../../utils/paths");
11
12
  const tsutils_1 = require("../../utils/tsutils");
12
13
  const validation_1 = require("../../utils/validation");
13
- const paths_1 = require("../../utils/paths");
14
+ let transientCount = 0;
15
+ const transientIds = new WeakMap();
14
16
  /**
15
17
  * This exists so that TypeDoc can store a unique identifier for a `ts.Symbol` without
16
18
  * keeping a reference to the `ts.Symbol` itself. This identifier should be stable across
@@ -20,7 +22,7 @@ class ReflectionSymbolId {
20
22
  constructor(symbol, declaration) {
21
23
  if ("name" in symbol) {
22
24
  declaration ??= symbol?.declarations?.[0];
23
- this.fileName = (0, paths_1.normalizePath)(declaration?.getSourceFile().fileName ?? "\0");
25
+ this.fileName = (0, paths_1.normalizePath)(declaration?.getSourceFile().fileName ?? "");
24
26
  if (symbol.declarations?.some(typescript_1.default.isSourceFile)) {
25
27
  this.qualifiedName = "";
26
28
  }
@@ -28,37 +30,43 @@ class ReflectionSymbolId {
28
30
  this.qualifiedName = (0, tsutils_1.getQualifiedName)(symbol, symbol.name);
29
31
  }
30
32
  this.pos = declaration?.pos ?? Infinity;
33
+ if (symbol.flags & typescript_1.default.SymbolFlags.Transient) {
34
+ this.transientId = transientIds.get(symbol) ?? ++transientCount;
35
+ transientIds.set(symbol, this.transientId);
36
+ }
37
+ else {
38
+ this.transientId = NaN;
39
+ }
31
40
  }
32
41
  else {
33
42
  this.fileName = symbol.sourceFileName;
34
43
  this.qualifiedName = symbol.qualifiedName;
35
44
  this.pos = Infinity;
45
+ this.transientId = NaN;
36
46
  }
37
47
  }
38
48
  getStableKey() {
39
49
  if (Number.isFinite(this.pos)) {
40
- return `${this.fileName}\0${this.qualifiedName}\0${this.pos}`;
50
+ return `${this.fileName}\0${this.qualifiedName}\0${this.pos}\0${this.transientId}`;
41
51
  }
42
52
  else {
43
53
  return `${this.fileName}\0${this.qualifiedName}`;
44
54
  }
45
55
  }
46
56
  toObject(serializer) {
57
+ const sourceFileName = (0, path_1.isAbsolute)(this.fileName)
58
+ ? (0, paths_1.normalizePath)((0, path_1.relative)(serializer.projectRoot, resolveDeclarationMaps(this.fileName)))
59
+ : this.fileName;
47
60
  return {
48
- sourceFileName: (0, path_1.isAbsolute)(this.fileName)
49
- ? (0, paths_1.normalizePath)((0, path_1.relative)(serializer.projectRoot, resolveDeclarationMaps(this.fileName)))
50
- : this.fileName,
61
+ sourceFileName,
51
62
  qualifiedName: this.qualifiedName,
52
63
  };
53
64
  }
54
65
  }
55
66
  exports.ReflectionSymbolId = ReflectionSymbolId;
56
67
  const declarationMapCache = new Map();
57
- /**
58
- * See also getTsSourceFromJsSource in package-manifest.ts.
59
- */
60
68
  function resolveDeclarationMaps(file) {
61
- if (!file.endsWith(".d.ts"))
69
+ if (!/\.d\.[cm]?ts$/.test(file))
62
70
  return file;
63
71
  if (declarationMapCache.has(file))
64
72
  return declarationMapCache.get(file);
@@ -93,3 +101,12 @@ function resolveDeclarationMaps(file) {
93
101
  }
94
102
  return file;
95
103
  }
104
+ function addInferredDeclarationMapPaths(opts, files) {
105
+ const rootDir = opts.rootDir || (0, fs_2.getCommonDirectory)(files);
106
+ const declDir = opts.declarationDir || opts.outDir || rootDir;
107
+ for (const file of files) {
108
+ const mapFile = (0, paths_1.normalizePath)((0, path_1.resolve)(declDir, (0, path_1.relative)(rootDir, file)).replace(/\.([cm]?[tj]s)x?$/, ".d.$1"));
109
+ declarationMapCache.set(mapFile, file);
110
+ }
111
+ }
112
+ exports.addInferredDeclarationMapPaths = addInferredDeclarationMapPaths;