typedoc 0.28.15 → 0.28.17

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 (32) hide show
  1. package/dist/lib/converter/comments/declarationReferenceResolver.js +3 -0
  2. package/dist/lib/converter/comments/discovery.js +79 -22
  3. package/dist/lib/converter/comments/index.d.ts +1 -1
  4. package/dist/lib/converter/comments/index.js +69 -18
  5. package/dist/lib/converter/factories/signature.d.ts +1 -0
  6. package/dist/lib/converter/factories/signature.js +13 -0
  7. package/dist/lib/converter/jsdoc.d.ts +1 -1
  8. package/dist/lib/converter/jsdoc.js +33 -2
  9. package/dist/lib/converter/plugins/CommentPlugin.d.ts +2 -0
  10. package/dist/lib/converter/plugins/CommentPlugin.js +17 -4
  11. package/dist/lib/converter/plugins/ImplementsPlugin.d.ts +1 -0
  12. package/dist/lib/converter/plugins/ImplementsPlugin.js +23 -4
  13. package/dist/lib/converter/plugins/IncludePlugin.js +4 -0
  14. package/dist/lib/converter/plugins/SourcePlugin.js +3 -3
  15. package/dist/lib/converter/symbols.js +1 -14
  16. package/dist/lib/converter/types.js +1 -1
  17. package/dist/lib/internationalization/locales/en.cjs +1 -0
  18. package/dist/lib/internationalization/locales/en.d.cts +1 -0
  19. package/dist/lib/models/Comment.d.ts +1 -1
  20. package/dist/lib/models/Comment.js +1 -1
  21. package/dist/lib/output/themes/MarkedPlugin.js +15 -8
  22. package/dist/lib/output/themes/default/Slugger.js +8 -2
  23. package/dist/lib/output/themes/default/partials/icon.js +1 -1
  24. package/dist/lib/utils/entry-point.js +1 -1
  25. package/dist/lib/utils/options/declaration.d.ts +1 -1
  26. package/dist/lib/utils-common/jsx.elements.d.ts +1 -0
  27. package/dist/lib/utils-common/path.d.ts +1 -0
  28. package/dist/lib/utils-common/path.js +4 -0
  29. package/dist/lib/utils-common/set.d.ts +1 -0
  30. package/dist/lib/utils-common/set.js +7 -0
  31. package/package.json +5 -3
  32. package/typedoc-config.schema.json +941 -0
@@ -13,6 +13,9 @@ export function resolveDeclarationReference(reflection, ref) {
13
13
  if (ref.moduleSource) {
14
14
  high = reflection.project.children?.filter((c) => c.kindOf(ReflectionKind.SomeModule) &&
15
15
  c.name === ref.moduleSource) || [];
16
+ if (!high.length && reflection.project.packageName === ref.moduleSource) {
17
+ high.push(reflection.project);
18
+ }
16
19
  }
17
20
  else if (ref.resolutionStart === "global") {
18
21
  high.push(reflection.project);
@@ -23,6 +23,8 @@ const variablePropertyKinds = [
23
23
  // Comments from @typedef and @callback tags are handled specially by
24
24
  // the JSDoc converter because we only want part of the comment when
25
25
  // getting them.
26
+ // This also does NOT include kinds which should be checked after the
27
+ // first kind/kinds have been checked for a comment.
26
28
  const wantedKinds = {
27
29
  [ReflectionKind.Project]: [
28
30
  ts.SyntaxKind.SourceFile,
@@ -38,24 +40,12 @@ const wantedKinds = {
38
40
  ts.SyntaxKind.BindingElement,
39
41
  ts.SyntaxKind.ExportSpecifier,
40
42
  ts.SyntaxKind.NamespaceExport,
41
- // @namespace support
42
- ts.SyntaxKind.VariableDeclaration,
43
- ts.SyntaxKind.BindingElement,
44
- ts.SyntaxKind.ExportAssignment,
45
- ts.SyntaxKind.PropertyAccessExpression,
46
- ts.SyntaxKind.PropertyDeclaration,
47
- ts.SyntaxKind.PropertyAssignment,
48
- ts.SyntaxKind.ShorthandPropertyAssignment,
49
43
  ],
50
44
  [ReflectionKind.Enum]: [
51
45
  ts.SyntaxKind.EnumDeclaration,
52
- ts.SyntaxKind.VariableDeclaration,
53
46
  ],
54
47
  [ReflectionKind.EnumMember]: [
55
48
  ts.SyntaxKind.EnumMember,
56
- // These here so that @enum gets comments
57
- ts.SyntaxKind.PropertyAssignment,
58
- ts.SyntaxKind.PropertySignature,
59
49
  ],
60
50
  [ReflectionKind.Variable]: variablePropertyKinds,
61
51
  [ReflectionKind.Function]: [
@@ -71,15 +61,9 @@ const wantedKinds = {
71
61
  [ReflectionKind.Class]: [
72
62
  ts.SyntaxKind.ClassDeclaration,
73
63
  ts.SyntaxKind.BindingElement,
74
- // If marked with @class
75
- ts.SyntaxKind.VariableDeclaration,
76
- ts.SyntaxKind.ExportAssignment,
77
- ts.SyntaxKind.FunctionDeclaration,
78
64
  ],
79
65
  [ReflectionKind.Interface]: [
80
66
  ts.SyntaxKind.InterfaceDeclaration,
81
- ts.SyntaxKind.TypeAliasDeclaration,
82
- ts.SyntaxKind.ClassDeclaration, // type only exports
83
67
  ],
84
68
  [ReflectionKind.Constructor]: [ts.SyntaxKind.Constructor],
85
69
  [ReflectionKind.Property]: variablePropertyKinds,
@@ -106,9 +90,6 @@ const wantedKinds = {
106
90
  [ReflectionKind.SetSignature]: [ts.SyntaxKind.SetAccessor],
107
91
  [ReflectionKind.TypeAlias]: [
108
92
  ts.SyntaxKind.TypeAliasDeclaration,
109
- ts.SyntaxKind.FunctionDeclaration, // type only exports
110
- // Intentionally not included to avoid comments being copied for variable/alias combos
111
- // ts.SyntaxKind.VariableDeclaration,
112
93
  ],
113
94
  [ReflectionKind.Reference]: [
114
95
  ts.SyntaxKind.NamespaceExport,
@@ -117,6 +98,72 @@ const wantedKinds = {
117
98
  // Non-TS kind, will never have comments.
118
99
  [ReflectionKind.Document]: [],
119
100
  };
101
+ // These kinds are checked after wantedKinds if wantedKinds doesn't result in
102
+ // discovering a comment. This is a rather unfortunate tradeoff between discovering
103
+ // comments for values in unusual circumstances (#2970) and avoiding duplicate
104
+ // comments being discovered for declaration merging nastiness (#3064)
105
+ const backupWantedKinds = {
106
+ [ReflectionKind.Project]: [],
107
+ [ReflectionKind.Module]: [],
108
+ [ReflectionKind.Namespace]: [
109
+ // @namespace support
110
+ ts.SyntaxKind.VariableDeclaration,
111
+ ts.SyntaxKind.BindingElement,
112
+ ts.SyntaxKind.ExportAssignment,
113
+ ts.SyntaxKind.PropertyAccessExpression,
114
+ ts.SyntaxKind.PropertyDeclaration,
115
+ ts.SyntaxKind.PropertyAssignment,
116
+ ts.SyntaxKind.ShorthandPropertyAssignment,
117
+ ],
118
+ [ReflectionKind.Enum]: [
119
+ ts.SyntaxKind.VariableDeclaration,
120
+ ],
121
+ [ReflectionKind.EnumMember]: [
122
+ // These here so that @enum gets comments
123
+ ts.SyntaxKind.PropertyAssignment,
124
+ ts.SyntaxKind.PropertySignature,
125
+ ],
126
+ [ReflectionKind.Variable]: [],
127
+ [ReflectionKind.Function]: [
128
+ ts.SyntaxKind.FunctionDeclaration,
129
+ ts.SyntaxKind.BindingElement,
130
+ ts.SyntaxKind.VariableDeclaration,
131
+ ts.SyntaxKind.ExportAssignment,
132
+ ts.SyntaxKind.PropertyAccessExpression,
133
+ ts.SyntaxKind.PropertyDeclaration,
134
+ ts.SyntaxKind.PropertyAssignment,
135
+ ts.SyntaxKind.ShorthandPropertyAssignment,
136
+ ],
137
+ [ReflectionKind.Class]: [
138
+ // If marked with @class
139
+ ts.SyntaxKind.VariableDeclaration,
140
+ ts.SyntaxKind.ExportAssignment,
141
+ ts.SyntaxKind.FunctionDeclaration,
142
+ ],
143
+ [ReflectionKind.Interface]: [
144
+ ts.SyntaxKind.TypeAliasDeclaration,
145
+ ts.SyntaxKind.ClassDeclaration, // type only exports
146
+ ],
147
+ [ReflectionKind.Constructor]: [],
148
+ [ReflectionKind.Property]: [],
149
+ [ReflectionKind.Method]: [],
150
+ [ReflectionKind.CallSignature]: [],
151
+ [ReflectionKind.IndexSignature]: [],
152
+ [ReflectionKind.ConstructorSignature]: [],
153
+ [ReflectionKind.Parameter]: [],
154
+ [ReflectionKind.TypeLiteral]: [],
155
+ [ReflectionKind.TypeParameter]: [],
156
+ [ReflectionKind.Accessor]: [],
157
+ [ReflectionKind.GetSignature]: [],
158
+ [ReflectionKind.SetSignature]: [],
159
+ [ReflectionKind.TypeAlias]: [
160
+ ts.SyntaxKind.FunctionDeclaration, // type only exports
161
+ ts.SyntaxKind.VariableDeclaration, // type only exports
162
+ ],
163
+ [ReflectionKind.Reference]: [],
164
+ // Non-TS kind, will never have comments.
165
+ [ReflectionKind.Document]: [],
166
+ };
120
167
  export function discoverFileComments(node, commentStyle) {
121
168
  const text = node.text;
122
169
  const comments = collectCommentRanges(ts.getLeadingCommentRanges(text, node.pos));
@@ -165,10 +212,20 @@ function checkCommentDeclarations(commentNodes, reverse, commentStyle) {
165
212
  return discovered;
166
213
  }
167
214
  export function discoverComment(symbol, kind, logger, commentStyle, checker, declarationWarnings) {
215
+ const discovered = discoverCommentWorker(symbol, kind, logger, commentStyle, checker, declarationWarnings, wantedKinds[kind]);
216
+ if (discovered) {
217
+ return discovered;
218
+ }
219
+ return discoverCommentWorker(symbol, kind, logger, commentStyle, checker, declarationWarnings, backupWantedKinds[kind]);
220
+ }
221
+ function discoverCommentWorker(symbol, kind, logger, commentStyle, checker, declarationWarnings, wanted) {
222
+ if (wanted.length === 0) {
223
+ return;
224
+ }
168
225
  // For a module comment, we want the first one defined in the file,
169
226
  // not the last one, since that will apply to the import or declaration.
170
227
  const reverse = !symbol.declarations?.some(ts.isSourceFile);
171
- const wantedDeclarations = filter(symbol.declarations, (decl) => wantedKinds[kind].includes(decl.kind));
228
+ const wantedDeclarations = filter(symbol.declarations, (decl) => wanted.includes(decl.kind));
172
229
  const commentNodes = wantedDeclarations.flatMap((decl) => declarationToCommentNodes(decl, checker));
173
230
  // Special behavior here!
174
231
  // Signatures and symbols have two distinct discovery methods as of TypeDoc 0.26.
@@ -2,7 +2,7 @@ import ts from "typescript";
2
2
  import { Comment, ReflectionKind } from "../../models/index.js";
3
3
  import type { CommentStyle, JsDocCompatibility, ValidationOptions } from "../../utils/options/declaration.js";
4
4
  import type { FileRegistry } from "../../models/FileRegistry.js";
5
- import { type Logger } from "#utils";
5
+ import { Logger } from "#utils";
6
6
  import type { Context } from "../context.js";
7
7
  export interface CommentParserConfig {
8
8
  blockTags: Set<string>;
@@ -4,7 +4,7 @@ import { lexBlockComment } from "./blockLexer.js";
4
4
  import { discoverComment, discoverFileComments, discoverNodeComment, discoverSignatureComment, } from "./discovery.js";
5
5
  import { lexLineComments } from "./lineLexer.js";
6
6
  import { parseComment } from "./parser.js";
7
- import { assertNever, i18n } from "#utils";
7
+ import { assertNever, i18n, Logger, setUnion } from "#utils";
8
8
  const jsDocCommentKinds = [
9
9
  ts.SyntaxKind.JSDocPropertyTag,
10
10
  ts.SyntaxKind.JSDocCallbackTag,
@@ -21,16 +21,10 @@ export function clearCommentCache() {
21
21
  commentCache = new WeakMap();
22
22
  commentDiscoveryId = 0;
23
23
  }
24
- function getCommentWithCache(discovered, context) {
24
+ function getCommentIgnoringCacheNoDiscoveryId(discovered, context) {
25
25
  if (!discovered)
26
26
  return;
27
27
  const { file, ranges, jsDoc } = discovered;
28
- const cache = commentCache.get(file) || new Map();
29
- if (cache.has(ranges[0].pos)) {
30
- const clone = cache.get(ranges[0].pos).clone();
31
- clone.inheritedFromParentDeclaration = discovered.inheritedFromParentDeclaration;
32
- return clone;
33
- }
34
28
  let comment;
35
29
  switch (ranges[0].kind) {
36
30
  case ts.SyntaxKind.MultiLineCommentTrivia:
@@ -42,8 +36,23 @@ function getCommentWithCache(discovered, context) {
42
36
  default:
43
37
  assertNever(ranges[0].kind);
44
38
  }
45
- comment.discoveryId = ++commentDiscoveryId;
46
39
  comment.inheritedFromParentDeclaration = discovered.inheritedFromParentDeclaration;
40
+ return comment;
41
+ }
42
+ function getCommentWithCache(discovered, context) {
43
+ if (!discovered)
44
+ return;
45
+ const { file, ranges } = discovered;
46
+ const cache = commentCache.get(file) || new Map();
47
+ if (cache.has(ranges[0].pos)) {
48
+ const clone = cache.get(ranges[0].pos).clone();
49
+ clone.inheritedFromParentDeclaration = discovered.inheritedFromParentDeclaration;
50
+ return clone;
51
+ }
52
+ const comment = getCommentIgnoringCacheNoDiscoveryId(discovered, context);
53
+ if (!comment)
54
+ return;
55
+ comment.discoveryId = ++commentDiscoveryId;
47
56
  cache.set(ranges[0].pos, comment);
48
57
  commentCache.set(file, cache);
49
58
  return comment.clone();
@@ -99,14 +108,24 @@ export function getNodeComment(node, moduleComment, context) {
99
108
  return getCommentImpl(discoverNodeComment(node, context.config.commentStyle), moduleComment, context);
100
109
  }
101
110
  export function getFileComment(file, context) {
111
+ const quietContext = {
112
+ ...context,
113
+ logger: new Logger(),
114
+ };
102
115
  for (const commentSource of discoverFileComments(file, context.config.commentStyle)) {
103
- const comment = getCommentWithCache(commentSource, context);
116
+ // First parse the comment without adding the parse to the cache
117
+ // and without logging any messages. If we end up not using this as
118
+ // a file comment we want to avoid parsing it with warnings here as
119
+ // it might be associated with a JSDoc parse which has special
120
+ // handling to allow modifier tags to be specified as {@mod}
121
+ // and if it gets added to the cache here we'll get unwanted warnings
122
+ const comment = getCommentIgnoringCacheNoDiscoveryId(commentSource, quietContext);
104
123
  if (comment?.getTag("@license") || comment?.getTag("@import")) {
105
124
  continue;
106
125
  }
107
126
  if (comment?.getTag("@module") ||
108
127
  comment?.hasModifier("@packageDocumentation")) {
109
- return comment;
128
+ return getCommentWithCache(commentSource, context);
110
129
  }
111
130
  return;
112
131
  }
@@ -127,6 +146,33 @@ function getConstructorParamPropertyComment(symbol, context) {
127
146
  export function getSignatureComment(declaration, context) {
128
147
  return getCommentImpl(discoverSignatureComment(declaration, context.checker, context.config.commentStyle), false, context);
129
148
  }
149
+ function buildJsDocCommentFromParts(declaration, parts, sourceComment, context) {
150
+ if (!parts) {
151
+ return undefined;
152
+ }
153
+ const comment = new Comment(Comment.cloneDisplayParts(parts));
154
+ comment.sourcePath = sourceComment.sourcePath;
155
+ for (let i = 0; i < comment.summary.length;) {
156
+ const part = comment.summary[i];
157
+ if (part.kind === "inline-tag" &&
158
+ !part.text.trim() &&
159
+ context.config.modifierTags.has(part.tag)) {
160
+ comment.modifierTags.add(part.tag);
161
+ comment.summary.splice(i, 1);
162
+ }
163
+ else if (part.kind === "inline-tag" &&
164
+ part.text.trim() &&
165
+ context.config.modifierTags.has(part.tag) &&
166
+ !context.config.inlineTags.has(part.tag)) {
167
+ context.logger.warn(i18n.inline_tag_0_not_parsed_as_modifier_tag_1(part.tag, part.text.trim()), declaration);
168
+ ++i;
169
+ }
170
+ else {
171
+ ++i;
172
+ }
173
+ }
174
+ return comment;
175
+ }
130
176
  export function getJsDocComment(declaration, context) {
131
177
  const file = declaration.getSourceFile();
132
178
  // First, get the whole comment. We know we'll need all of it.
@@ -134,6 +180,15 @@ export function getJsDocComment(declaration, context) {
134
180
  while (!ts.isJSDoc(parent)) {
135
181
  parent = parent.parent;
136
182
  }
183
+ // Build a custom context to allow modifier tags to be written as inline
184
+ // tags as otherwise there's no way to specify them here #2916 #3050
185
+ const contextWithInline = {
186
+ ...context,
187
+ config: {
188
+ ...context.config,
189
+ inlineTags: setUnion(context.config.inlineTags, context.config.modifierTags),
190
+ },
191
+ };
137
192
  // Then parse it.
138
193
  const comment = getCommentWithCache({
139
194
  file,
@@ -146,12 +201,10 @@ export function getJsDocComment(declaration, context) {
146
201
  ],
147
202
  jsDoc: parent,
148
203
  inheritedFromParentDeclaration: false,
149
- }, context);
204
+ }, contextWithInline);
150
205
  // And pull out the tag we actually care about.
151
206
  if (ts.isJSDocEnumTag(declaration)) {
152
- const result = new Comment(comment.getTag("@enum")?.content);
153
- result.sourcePath = comment.sourcePath;
154
- return result;
207
+ return buildJsDocCommentFromParts(declaration, comment.getTag("@enum")?.content, comment, context);
155
208
  }
156
209
  if (ts.isJSDocTemplateTag(declaration) &&
157
210
  declaration.comment &&
@@ -183,8 +236,6 @@ export function getJsDocComment(declaration, context) {
183
236
  }
184
237
  }
185
238
  else {
186
- const result = new Comment(Comment.cloneDisplayParts(tag.content));
187
- result.sourcePath = comment.sourcePath;
188
- return result;
239
+ return buildJsDocCommentFromParts(declaration, tag.content, comment, context);
189
240
  }
190
241
  }
@@ -1,6 +1,7 @@
1
1
  import ts from "typescript";
2
2
  import { ParameterReflection, type Reflection, ReflectionKind, SignatureReflection, TypeParameterReflection } from "../../models/index.js";
3
3
  import type { Context } from "../context.js";
4
+ export declare function convertConstructSignatures(context: Context, symbol: ts.Symbol): void;
4
5
  export declare function createSignature(context: Context, kind: ReflectionKind.CallSignature | ReflectionKind.ConstructorSignature | ReflectionKind.GetSignature | ReflectionKind.SetSignature, signature: ts.Signature, symbol: ts.Symbol | undefined, declaration?: ts.SignatureDeclaration | ts.JSDocSignature): void;
5
6
  /**
6
7
  * Special cased constructor factory for functions tagged with `@class`
@@ -4,6 +4,19 @@ import { DeclarationReflection, IntrinsicType, ParameterReflection, PredicateTyp
4
4
  import { ConverterEvents } from "../converter-events.js";
5
5
  import { convertDefaultValue } from "../convert-expression.js";
6
6
  import { removeUndefined } from "../utils/reflections.js";
7
+ export function convertConstructSignatures(context, symbol) {
8
+ const type = context.checker.getDeclaredTypeOfSymbol(symbol);
9
+ // These get added as a "constructor" member of this interface. This is a problem... but nobody
10
+ // has complained yet. We really ought to have a constructSignatures property on the reflection instead.
11
+ const constructSignatures = context.checker.getSignaturesOfType(type, ts.SignatureKind.Construct);
12
+ if (constructSignatures.length) {
13
+ const constructMember = new DeclarationReflection("constructor", ReflectionKind.Constructor, context.scope);
14
+ context.postReflectionCreation(constructMember, symbol, void 0);
15
+ context.finalizeDeclarationReflection(constructMember);
16
+ const constructContext = context.withScope(constructMember);
17
+ constructSignatures.forEach((sig) => createSignature(constructContext, ReflectionKind.ConstructorSignature, sig, symbol));
18
+ }
19
+ }
7
20
  export function createSignature(context, kind, signature, symbol, declaration) {
8
21
  assert(context.scope instanceof DeclarationReflection);
9
22
  declaration ||= signature.getDeclaration();
@@ -1,4 +1,4 @@
1
1
  import ts from "typescript";
2
2
  import type { Context } from "./context.js";
3
- export declare function convertJsDocAlias(context: Context, symbol: ts.Symbol, declaration: ts.JSDocTypedefTag | ts.JSDocEnumTag, exportSymbol?: ts.Symbol): void;
3
+ export declare function convertJsDocAlias(context: Context, symbol: ts.Symbol, declaration: ts.JSDocTypedefTag | ts.JSDocEnumTag, exportSymbol?: ts.Symbol): undefined;
4
4
  export declare function convertJsDocCallback(context: Context, symbol: ts.Symbol, declaration: ts.JSDocCallbackTag, exportSymbol?: ts.Symbol): void;
@@ -5,13 +5,44 @@ import { ok } from "assert";
5
5
  import ts from "typescript";
6
6
  import { DeclarationReflection, IntrinsicType, ReflectionKind, ReflectionType, SignatureReflection, } from "../models/index.js";
7
7
  import { ConverterEvents } from "./converter-events.js";
8
- import { convertParameterNodes, convertTemplateParameterNodes } from "./factories/signature.js";
8
+ import { convertConstructSignatures, convertParameterNodes, convertTemplateParameterNodes, createSignature, } from "./factories/signature.js";
9
+ import { i18n } from "#utils";
10
+ import { convertIndexSignatures } from "./factories/index-signature.js";
11
+ // This is almost convertTypeAliasAsInterface, but unfortunately needs to be separate
12
+ // due to type parameters being different in JSDoc comments
13
+ function convertJsDocAliasAsInterface(context, symbol, exportSymbol, declaration) {
14
+ const reflection = context.createDeclarationReflection(ReflectionKind.Interface, symbol, exportSymbol);
15
+ context.finalizeDeclarationReflection(reflection);
16
+ const rc = context.withScope(reflection);
17
+ const type = context.checker.getTypeAtLocation(declaration);
18
+ if (type.getFlags() & ts.TypeFlags.Union) {
19
+ context.logger.warn(i18n.converting_union_as_interface(), declaration);
20
+ }
21
+ // Interfaces have properties
22
+ for (const prop of type.getProperties()) {
23
+ context.converter.convertSymbol(rc, prop);
24
+ }
25
+ // And type parameters
26
+ convertTemplateParameters(rc, declaration.parent);
27
+ // And maybe call signatures
28
+ context.checker
29
+ .getSignaturesOfType(type, ts.SignatureKind.Call)
30
+ .forEach((sig) => createSignature(rc, ReflectionKind.CallSignature, sig, symbol));
31
+ // And maybe constructor signatures
32
+ convertConstructSignatures(rc, symbol);
33
+ // And finally, index signatures
34
+ convertIndexSignatures(rc, type);
35
+ }
9
36
  export function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
10
37
  if (declaration.typeExpression &&
11
38
  ts.isJSDocTypeLiteral(declaration.typeExpression)) {
12
39
  convertJsDocInterface(context, declaration, symbol, exportSymbol);
13
40
  return;
14
41
  }
42
+ const comment = context.getJsDocComment(declaration);
43
+ if (comment?.hasModifier("@interface")) {
44
+ return convertJsDocAliasAsInterface(context, symbol, exportSymbol, declaration);
45
+ }
15
46
  // If the typedef tag is just referring to another type-space symbol, with no type parameters
16
47
  // or appropriate forwarding type parameters, then we treat it as a re-export instead of creating
17
48
  // a type alias with an import type.
@@ -21,7 +52,7 @@ export function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
21
52
  return;
22
53
  }
23
54
  const reflection = context.createDeclarationReflection(ReflectionKind.TypeAlias, symbol, exportSymbol);
24
- reflection.comment = context.getJsDocComment(declaration);
55
+ reflection.comment = comment;
25
56
  reflection.type = context.converter.convertType(context.withScope(reflection), declaration.typeExpression?.type);
26
57
  convertTemplateParameters(context.withScope(reflection), declaration.parent);
27
58
  context.finalizeDeclarationReflection(reflection);
@@ -66,6 +66,7 @@ export declare class CommentPlugin extends ConverterComponent {
66
66
  accessor excludeNotDocumented: boolean;
67
67
  accessor excludeCategories: string[];
68
68
  accessor defaultCategory: string;
69
+ accessor suppressCommentWarningsInDeclarationFiles: boolean;
69
70
  private _excludeKinds;
70
71
  private get excludeNotDocumentedKinds();
71
72
  constructor(owner: Converter);
@@ -123,4 +124,5 @@ export declare class CommentPlugin extends ConverterComponent {
123
124
  private isHidden;
124
125
  private excludedByCategory;
125
126
  private validateParamTags;
127
+ private suppressCommentWarnings;
126
128
  }
@@ -154,6 +154,9 @@ let CommentPlugin = (() => {
154
154
  let _defaultCategory_decorators;
155
155
  let _defaultCategory_initializers = [];
156
156
  let _defaultCategory_extraInitializers = [];
157
+ let _suppressCommentWarningsInDeclarationFiles_decorators;
158
+ let _suppressCommentWarningsInDeclarationFiles_initializers = [];
159
+ let _suppressCommentWarningsInDeclarationFiles_extraInitializers = [];
157
160
  return class CommentPlugin extends _classSuper {
158
161
  static {
159
162
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
@@ -166,6 +169,7 @@ let CommentPlugin = (() => {
166
169
  _excludeNotDocumented_decorators = [Option("excludeNotDocumented")];
167
170
  _excludeCategories_decorators = [Option("excludeCategories")];
168
171
  _defaultCategory_decorators = [Option("defaultCategory")];
172
+ _suppressCommentWarningsInDeclarationFiles_decorators = [Option("suppressCommentWarningsInDeclarationFiles")];
169
173
  __esDecorate(this, null, _excludeTags_decorators, { kind: "accessor", name: "excludeTags", static: false, private: false, access: { has: obj => "excludeTags" in obj, get: obj => obj.excludeTags, set: (obj, value) => { obj.excludeTags = value; } }, metadata: _metadata }, _excludeTags_initializers, _excludeTags_extraInitializers);
170
174
  __esDecorate(this, null, _cascadedModifierTags_decorators, { kind: "accessor", name: "cascadedModifierTags", static: false, private: false, access: { has: obj => "cascadedModifierTags" in obj, get: obj => obj.cascadedModifierTags, set: (obj, value) => { obj.cascadedModifierTags = value; } }, metadata: _metadata }, _cascadedModifierTags_initializers, _cascadedModifierTags_extraInitializers);
171
175
  __esDecorate(this, null, _excludeInternal_decorators, { kind: "accessor", name: "excludeInternal", static: false, private: false, access: { has: obj => "excludeInternal" in obj, get: obj => obj.excludeInternal, set: (obj, value) => { obj.excludeInternal = value; } }, metadata: _metadata }, _excludeInternal_initializers, _excludeInternal_extraInitializers);
@@ -175,6 +179,7 @@ let CommentPlugin = (() => {
175
179
  __esDecorate(this, null, _excludeNotDocumented_decorators, { kind: "accessor", name: "excludeNotDocumented", static: false, private: false, access: { has: obj => "excludeNotDocumented" in obj, get: obj => obj.excludeNotDocumented, set: (obj, value) => { obj.excludeNotDocumented = value; } }, metadata: _metadata }, _excludeNotDocumented_initializers, _excludeNotDocumented_extraInitializers);
176
180
  __esDecorate(this, null, _excludeCategories_decorators, { kind: "accessor", name: "excludeCategories", static: false, private: false, access: { has: obj => "excludeCategories" in obj, get: obj => obj.excludeCategories, set: (obj, value) => { obj.excludeCategories = value; } }, metadata: _metadata }, _excludeCategories_initializers, _excludeCategories_extraInitializers);
177
181
  __esDecorate(this, null, _defaultCategory_decorators, { kind: "accessor", name: "defaultCategory", static: false, private: false, access: { has: obj => "defaultCategory" in obj, get: obj => obj.defaultCategory, set: (obj, value) => { obj.defaultCategory = value; } }, metadata: _metadata }, _defaultCategory_initializers, _defaultCategory_extraInitializers);
182
+ __esDecorate(this, null, _suppressCommentWarningsInDeclarationFiles_decorators, { kind: "accessor", name: "suppressCommentWarningsInDeclarationFiles", static: false, private: false, access: { has: obj => "suppressCommentWarningsInDeclarationFiles" in obj, get: obj => obj.suppressCommentWarningsInDeclarationFiles, set: (obj, value) => { obj.suppressCommentWarningsInDeclarationFiles = value; } }, metadata: _metadata }, _suppressCommentWarningsInDeclarationFiles_initializers, _suppressCommentWarningsInDeclarationFiles_extraInitializers);
178
183
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
179
184
  }
180
185
  #excludeTags_accessor_storage = __runInitializers(this, _excludeTags_initializers, void 0);
@@ -204,7 +209,10 @@ let CommentPlugin = (() => {
204
209
  #defaultCategory_accessor_storage = (__runInitializers(this, _excludeCategories_extraInitializers), __runInitializers(this, _defaultCategory_initializers, void 0));
205
210
  get defaultCategory() { return this.#defaultCategory_accessor_storage; }
206
211
  set defaultCategory(value) { this.#defaultCategory_accessor_storage = value; }
207
- _excludeKinds = __runInitializers(this, _defaultCategory_extraInitializers);
212
+ #suppressCommentWarningsInDeclarationFiles_accessor_storage = (__runInitializers(this, _defaultCategory_extraInitializers), __runInitializers(this, _suppressCommentWarningsInDeclarationFiles_initializers, void 0));
213
+ get suppressCommentWarningsInDeclarationFiles() { return this.#suppressCommentWarningsInDeclarationFiles_accessor_storage; }
214
+ set suppressCommentWarningsInDeclarationFiles(value) { this.#suppressCommentWarningsInDeclarationFiles_accessor_storage = value; }
215
+ _excludeKinds = __runInitializers(this, _suppressCommentWarningsInDeclarationFiles_extraInitializers);
208
216
  get excludeNotDocumentedKinds() {
209
217
  this._excludeKinds ??= this.application.options
210
218
  .getValue("excludeNotDocumentedKinds")
@@ -407,12 +415,13 @@ let CommentPlugin = (() => {
407
415
  onResolve(context, reflection) {
408
416
  if (reflection.comment) {
409
417
  if (reflection.comment.label &&
410
- !/[A-Z_][A-Z0-9_]/.test(reflection.comment.label)) {
418
+ !/[A-Z_][A-Z0-9_]/.test(reflection.comment.label) &&
419
+ !this.suppressCommentWarnings(reflection.comment)) {
411
420
  context.logger.warn(i18n.label_0_for_1_cannot_be_referenced(reflection.comment.label, reflection.getFriendlyFullName()));
412
421
  }
413
422
  for (const group of MUTUALLY_EXCLUSIVE_MODIFIERS) {
414
423
  const intersect = setIntersection(group, reflection.comment.modifierTags);
415
- if (intersect.size > 1) {
424
+ if (intersect.size > 1 && !this.suppressCommentWarnings(reflection.comment)) {
416
425
  const [a, b] = intersect;
417
426
  context.logger.warn(i18n.modifier_tag_0_is_mutually_exclusive_with_1_in_comment_for_2(a, b, reflection.getFriendlyFullName()));
418
427
  }
@@ -637,12 +646,16 @@ let CommentPlugin = (() => {
637
646
  const paramTags = comment.blockTags.filter((tag) => tag.tag === "@param");
638
647
  removeIf(paramTags, (tag) => params.some((param) => param.name === tag.name));
639
648
  moveNestedParamTags(/* in-out */ paramTags, params, comment.sourcePath);
640
- if (!comment.inheritedFromParentDeclaration) {
649
+ if (!comment.inheritedFromParentDeclaration && !this.suppressCommentWarnings(comment)) {
641
650
  for (const tag of paramTags) {
642
651
  this.application.logger.warn(i18n.signature_0_has_unused_param_with_name_1(signature.getFriendlyFullName(), tag.name ?? "(missing)"));
643
652
  }
644
653
  }
645
654
  }
655
+ suppressCommentWarnings(comment) {
656
+ return this.suppressCommentWarningsInDeclarationFiles &&
657
+ /\.d\.(ts|mts|cts)$/.test(comment.sourcePath || "");
658
+ }
646
659
  };
647
660
  })();
648
661
  export { CommentPlugin };
@@ -14,6 +14,7 @@ export declare class ImplementsPlugin extends ConverterComponent {
14
14
  */
15
15
  private analyzeImplements;
16
16
  private analyzeInheritance;
17
+ private cleanUpImplements;
17
18
  private onResolveEnd;
18
19
  private onRevive;
19
20
  private resolve;
@@ -95,10 +95,6 @@ export class ImplementsPlugin extends ConverterComponent {
95
95
  // serialization/deserialization, might point to an unexpected location. (See the mixin
96
96
  // converter tests, I suspect this might actually be an indication of something else slightly
97
97
  // broken there, but don't want to spend more time with this right now.)
98
- // #2982/#3007, even more unfortunately, we only want to keep the link if it is pointing
99
- // to a reflection which will receive a link during rendering, we pick this based on it being
100
- // the type of member we expect to point to.
101
- const isValidRef = (ref) => !!ref.reflection?.parent?.kindOf(ReflectionKind.ClassOrInterface | ReflectionKind.Method | ReflectionKind.Constructor);
102
98
  for (const child of reflection.children || []) {
103
99
  if (child.inheritedFrom && !isValidRef(child.inheritedFrom)) {
104
100
  child.inheritedFrom = ReferenceType.createBrokenReference(child.inheritedFrom.name, project, child.inheritedFrom.package);
@@ -116,6 +112,19 @@ export class ImplementsPlugin extends ConverterComponent {
116
112
  }
117
113
  }
118
114
  }
115
+ cleanUpImplements(project, reflection) {
116
+ // #3052, the same problem as #2978 applies for implements
117
+ for (const child of reflection.children || []) {
118
+ if (child.implementationOf && !isValidRef(child.implementationOf)) {
119
+ child.implementationOf = ReferenceType.createBrokenReference(child.implementationOf.name, project, child.implementationOf.package);
120
+ }
121
+ for (const childSig of child.getAllSignatures()) {
122
+ if (childSig.implementationOf && !isValidRef(childSig.implementationOf)) {
123
+ childSig.implementationOf = ReferenceType.createBrokenReference(childSig.implementationOf.name, project, childSig.implementationOf.package);
124
+ }
125
+ }
126
+ }
127
+ }
119
128
  onResolveEnd(context) {
120
129
  this.resolve(context.project);
121
130
  }
@@ -184,6 +193,10 @@ export class ImplementsPlugin extends ConverterComponent {
184
193
  reflection.extendedTypes) {
185
194
  this.analyzeInheritance(project, reflection);
186
195
  }
196
+ if (reflection.kindOf(ReflectionKind.ClassOrInterface) &&
197
+ (reflection.extendedTypes || reflection.implementedTypes)) {
198
+ this.cleanUpImplements(project, reflection);
199
+ }
187
200
  }
188
201
  getExtensionInfo(context, reflection) {
189
202
  if (!reflection || !reflection.kindOf(ReflectionKind.Inheritable)) {
@@ -417,3 +430,9 @@ function findMatchingMember(toMatch, container) {
417
430
  return container.children?.find((child) => child.name == toMatch.name &&
418
431
  child.flags.isStatic === toMatch.flags.isStatic);
419
432
  }
433
+ // #2982/#3007 unfortunately, we only want to keep the link if it is pointing
434
+ // to a reflection which will receive a link during rendering, we pick this based on it being
435
+ // the type of member we expect to point to.
436
+ function isValidRef(ref) {
437
+ return !!ref.reflection?.parent?.kindOf(ReflectionKind.ClassOrInterface | ReflectionKind.Method | ReflectionKind.Constructor);
438
+ }
@@ -246,5 +246,9 @@ regionTagREsByExt["php"] = regionTagREsByExt["cs"];
246
246
  regionTagREsByExt["ps1"] = regionTagREsByExt["cs"];
247
247
  regionTagREsByExt["py"] = regionTagREsByExt["cs"];
248
248
  regionTagREsByExt["js"] = regionTagREsByExt["ts"];
249
+ regionTagREsByExt["mjs"] = regionTagREsByExt["ts"];
249
250
  regionTagREsByExt["mts"] = regionTagREsByExt["ts"];
251
+ regionTagREsByExt["cjs"] = regionTagREsByExt["ts"];
250
252
  regionTagREsByExt["cts"] = regionTagREsByExt["ts"];
253
+ regionTagREsByExt["jsx"] = regionTagREsByExt["ts"];
254
+ regionTagREsByExt["tsx"] = regionTagREsByExt["ts"];
@@ -33,7 +33,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
33
33
  return useValue ? value : void 0;
34
34
  };
35
35
  import ts from "typescript";
36
- import { DeclarationReflection, SignatureReflection } from "../../models/index.js";
36
+ import { DeclarationReflection, ReflectionKind, SignatureReflection } from "../../models/index.js";
37
37
  import { ConverterComponent } from "../components.js";
38
38
  import { getCommonDirectory, normalizePath, Option } from "../../utils/index.js";
39
39
  import { isNamedNode } from "../utils/nodes.js";
@@ -120,7 +120,7 @@ let SourcePlugin = (() => {
120
120
  * @param reflection The reflection that is currently processed.
121
121
  */
122
122
  onDeclaration(context, reflection) {
123
- if (this.disableSources)
123
+ if (this.disableSources || reflection.kindOf(ReflectionKind.TypeLiteral))
124
124
  return;
125
125
  const symbol = context.getSymbolFromReflection(reflection);
126
126
  for (const node of symbol?.declarations || []) {
@@ -139,7 +139,7 @@ let SourcePlugin = (() => {
139
139
  }
140
140
  }
141
141
  onSignature(_context, reflection, sig) {
142
- if (this.disableSources || !sig)
142
+ if (this.disableSources || !sig || reflection.parent.kindOf(ReflectionKind.TypeLiteral))
143
143
  return;
144
144
  const sourceFile = sig.getSourceFile();
145
145
  const fileName = normalizePath(sourceFile.fileName);
@@ -4,7 +4,7 @@ import { DeclarationReflection, IntrinsicType, LiteralType, ReferenceReflection,
4
4
  import { getEnumFlags, hasAllFlags, hasAnyFlag, i18n, removeFlag } from "#utils";
5
5
  import { convertDefaultValue } from "./convert-expression.js";
6
6
  import { convertIndexSignatures } from "./factories/index-signature.js";
7
- import { convertTypeParameters, createConstructSignatureWithType, createSignature, createTypeParamReflection, } from "./factories/signature.js";
7
+ import { convertConstructSignatures, convertTypeParameters, createConstructSignatureWithType, createSignature, createTypeParamReflection, } from "./factories/signature.js";
8
8
  import { convertJsDocAlias, convertJsDocCallback } from "./jsdoc.js";
9
9
  import { getHeritageTypes } from "./utils/nodes.js";
10
10
  import { removeUndefined } from "./utils/reflections.js";
@@ -522,19 +522,6 @@ function convertConstructor(context, symbol) {
522
522
  createSignature(reflectionContext, ReflectionKind.ConstructorSignature, sig, symbol);
523
523
  }
524
524
  }
525
- function convertConstructSignatures(context, symbol) {
526
- const type = context.checker.getDeclaredTypeOfSymbol(symbol);
527
- // These get added as a "constructor" member of this interface. This is a problem... but nobody
528
- // has complained yet. We really ought to have a constructSignatures property on the reflection instead.
529
- const constructSignatures = context.checker.getSignaturesOfType(type, ts.SignatureKind.Construct);
530
- if (constructSignatures.length) {
531
- const constructMember = new DeclarationReflection("constructor", ReflectionKind.Constructor, context.scope);
532
- context.postReflectionCreation(constructMember, symbol, void 0);
533
- context.finalizeDeclarationReflection(constructMember);
534
- const constructContext = context.withScope(constructMember);
535
- constructSignatures.forEach((sig) => createSignature(constructContext, ReflectionKind.ConstructorSignature, sig, symbol));
536
- }
537
- }
538
525
  function convertAlias(context, symbol, exportSymbol) {
539
526
  // If this is a namespace marked as a primary export or directly within one
540
527
  // marked as a primary export then we should convert it immediately rather than deferring
@@ -477,7 +477,7 @@ const referenceConverter = {
477
477
  return convertTypeInlined(context, type);
478
478
  }
479
479
  const ref = context.createSymbolReference(context.resolveAliasedSymbol(symbol), context, name);
480
- if (type.flags & ts.TypeFlags.Substitution) {
480
+ if ((type.flags & ts.TypeFlags.Substitution) && name === "NoInfer" && ref.package === "typescript") {
481
481
  // NoInfer<T>
482
482
  ref.typeArguments = [
483
483
  convertType(context, type.baseType),