Skip to content

Commit 5409c0d

Browse files
committed
More test coverage improvements
1 parent 1bf3217 commit 5409c0d

File tree

26 files changed

+464
-231
lines changed

26 files changed

+464
-231
lines changed

src/lib/converter/comments/linkResolver.ts

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import ts from "typescript";
22
import {
3-
type Comment,
43
type CommentDisplayPart,
5-
DeclarationReflection,
64
type InlineTagDisplayPart,
5+
makeRecursiveVisitor,
76
Reflection,
87
ReflectionKind,
98
ReflectionSymbolId,
@@ -35,27 +34,28 @@ export type LinkResolverOptions = {
3534
};
3635

3736
export function resolveLinks(
38-
comment: Comment,
3937
reflection: Reflection,
4038
externalResolver: ExternalSymbolResolver,
4139
options: LinkResolverOptions,
4240
) {
43-
comment.summary = resolvePartLinks(
44-
reflection,
45-
comment.summary,
46-
externalResolver,
47-
options,
48-
);
49-
for (const tag of comment.blockTags) {
50-
tag.content = resolvePartLinks(
41+
if (reflection.comment) {
42+
reflection.comment.summary = resolvePartLinks(
5143
reflection,
52-
tag.content,
44+
reflection.comment.summary,
5345
externalResolver,
5446
options,
5547
);
48+
for (const tag of reflection.comment.blockTags) {
49+
tag.content = resolvePartLinks(
50+
reflection,
51+
tag.content,
52+
externalResolver,
53+
options,
54+
);
55+
}
5656
}
5757

58-
if (reflection instanceof DeclarationReflection && reflection.readme) {
58+
if ((reflection.isDeclaration() || reflection.isProject()) && reflection.readme) {
5959
reflection.readme = resolvePartLinks(
6060
reflection,
6161
reflection.readme,
@@ -64,6 +64,18 @@ export function resolveLinks(
6464
);
6565
}
6666

67+
if (reflection.isDeclaration()) {
68+
reflection.type?.visit(
69+
makeRecursiveVisitor({
70+
union: (type) => {
71+
type.elementSummaries = type.elementSummaries?.map(
72+
(parts) => resolvePartLinks(reflection, parts, externalResolver, options),
73+
);
74+
},
75+
}),
76+
);
77+
}
78+
6779
if (reflection.isDocument()) {
6880
reflection.content = resolvePartLinks(
6981
reflection,
@@ -72,6 +84,57 @@ export function resolveLinks(
7284
options,
7385
);
7486
}
87+
88+
if (
89+
reflection.isParameter() &&
90+
reflection.type?.type === "reference" &&
91+
reflection.type.highlightedProperties
92+
) {
93+
const resolved = new Map(
94+
Array.from(
95+
reflection.type.highlightedProperties,
96+
([name, parts]) => {
97+
return [
98+
name,
99+
resolvePartLinks(reflection, parts, externalResolver, options),
100+
];
101+
},
102+
),
103+
);
104+
105+
reflection.type.highlightedProperties = resolved;
106+
}
107+
108+
if (reflection.isContainer()) {
109+
if (reflection.groups) {
110+
for (const group of reflection.groups) {
111+
if (group.description) {
112+
group.description = resolvePartLinks(
113+
reflection,
114+
group.description,
115+
externalResolver,
116+
options,
117+
);
118+
}
119+
120+
if (group.categories) {
121+
for (const cat of group.categories) {
122+
if (cat.description) {
123+
cat.description = resolvePartLinks(reflection, cat.description, externalResolver, options);
124+
}
125+
}
126+
}
127+
}
128+
}
129+
130+
if (reflection.categories) {
131+
for (const cat of reflection.categories) {
132+
if (cat.description) {
133+
cat.description = resolvePartLinks(reflection, cat.description, externalResolver, options);
134+
}
135+
}
136+
}
137+
}
75138
}
76139

77140
export function resolvePartLinks(
@@ -133,10 +196,10 @@ function resolveLinkTag(
133196

134197
if (tsTargets.length) {
135198
// Find the target most likely to have a real url in the generated documentation
136-
// 1. A direct export (class, interface, variable)
137-
// 2. A property of a direct export (class/interface property)
138-
// 3. A property of a type of an export (property on type alias)
139-
// 4. Whatever the first symbol found was
199+
// 4. A direct export (class, interface, variable)
200+
// 3. A property of a direct export (class/interface property)
201+
// 2. A property of a type of an export (property on type alias)
202+
// 1. Whatever the first symbol found was
140203
target = maxElementByScore(tsTargets, (r) => {
141204
if (r.kindOf(ReflectionKind.SomeExport)) {
142205
return 4;

src/lib/converter/converter.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
DocumentReflection,
1111
type ParameterReflection,
1212
ProjectReflection,
13-
type Reflection,
13+
Reflection,
1414
ReflectionKind,
1515
type ReflectionSymbolId,
1616
type SignatureReflection,
@@ -436,25 +436,32 @@ export class Converter extends AbstractComponent<Application, ConverterEvents> {
436436
}
437437
}
438438

439+
resolveLinks(reflection: Reflection): void;
440+
/** @deprecated just pass the reflection */
439441
resolveLinks(comment: Comment, owner: Reflection): void;
440442
resolveLinks(
441443
parts: readonly CommentDisplayPart[],
442444
owner: Reflection,
443445
): CommentDisplayPart[];
444446
resolveLinks(
445-
comment: Comment | readonly CommentDisplayPart[],
446-
owner: Reflection,
447+
comment: Reflection | Comment | readonly CommentDisplayPart[],
448+
owner?: Reflection,
447449
): CommentDisplayPart[] | undefined {
448-
if (comment instanceof Comment) {
450+
if (comment instanceof Reflection) {
449451
resolveLinks(
450452
comment,
451-
owner,
453+
(ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id),
454+
{ preserveLinkText: this.preserveLinkText },
455+
);
456+
} else if (comment instanceof Comment) {
457+
resolveLinks(
458+
owner!,
452459
(ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id),
453460
{ preserveLinkText: this.preserveLinkText },
454461
);
455462
} else {
456463
return resolvePartLinks(
457-
owner,
464+
owner!,
458465
comment,
459466
(ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id),
460467
{ preserveLinkText: this.preserveLinkText },

src/lib/converter/plugins/LinkResolverPlugin.ts

Lines changed: 2 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,7 @@ import { ConverterComponent } from "../components.js";
22
import type { Context, Converter } from "../../converter/index.js";
33
import { ConverterEvents } from "../converter-events.js";
44
import { Option, type ValidationOptions } from "../../utils/index.js";
5-
import {
6-
ContainerReflection,
7-
makeRecursiveVisitor,
8-
type ProjectReflection,
9-
type Reflection,
10-
type ReflectionCategory,
11-
} from "../../models/index.js";
5+
import type { ProjectReflection } from "../../models/index.js";
126
import { discoverAllReferenceTypes } from "../../utils/reflections.js";
137
import { ApplicationEvents } from "../../application-events.js";
148

@@ -40,84 +34,7 @@ export class LinkResolverPlugin extends ConverterComponent {
4034
resolveLinks(project: ProjectReflection) {
4135
for (const id in project.reflections) {
4236
const reflection = project.reflections[id];
43-
if (reflection.comment) {
44-
this.owner.resolveLinks(reflection.comment, reflection);
45-
}
46-
47-
if (reflection.isDeclaration()) {
48-
reflection.type?.visit(
49-
makeRecursiveVisitor({
50-
union: (type) => {
51-
type.elementSummaries = type.elementSummaries?.map(
52-
(parts) => this.owner.resolveLinks(parts, reflection),
53-
);
54-
},
55-
}),
56-
);
57-
58-
if (reflection.readme) {
59-
reflection.readme = this.owner.resolveLinks(
60-
reflection.readme,
61-
reflection,
62-
);
63-
}
64-
}
65-
66-
if (reflection.isDocument()) {
67-
reflection.content = this.owner.resolveLinks(
68-
reflection.content,
69-
reflection,
70-
);
71-
}
72-
73-
if (
74-
reflection.isParameter() &&
75-
reflection.type?.type === "reference" &&
76-
reflection.type.highlightedProperties
77-
) {
78-
const resolved = new Map(
79-
Array.from(
80-
reflection.type.highlightedProperties,
81-
([name, parts]) => {
82-
return [
83-
name,
84-
this.owner.resolveLinks(parts, reflection),
85-
];
86-
},
87-
),
88-
);
89-
90-
reflection.type.highlightedProperties = resolved;
91-
}
92-
93-
if (reflection instanceof ContainerReflection) {
94-
if (reflection.groups) {
95-
for (const group of reflection.groups) {
96-
if (group.description) {
97-
group.description = this.owner.resolveLinks(
98-
group.description,
99-
reflection,
100-
);
101-
}
102-
103-
if (group.categories) {
104-
for (const cat of group.categories) {
105-
this.resolveCategoryLinks(cat, reflection);
106-
}
107-
}
108-
}
109-
}
110-
111-
if (reflection.categories) {
112-
for (const cat of reflection.categories) {
113-
this.resolveCategoryLinks(cat, reflection);
114-
}
115-
}
116-
}
117-
}
118-
119-
if (project.readme) {
120-
project.readme = this.owner.resolveLinks(project.readme, project);
37+
this.owner.resolveLinks(reflection);
12138
}
12239

12340
for (
@@ -144,16 +61,4 @@ export class LinkResolverPlugin extends ConverterComponent {
14461
}
14562
}
14663
}
147-
148-
private resolveCategoryLinks(
149-
category: ReflectionCategory,
150-
owner: Reflection,
151-
) {
152-
if (category.description) {
153-
category.description = this.owner.resolveLinks(
154-
category.description,
155-
owner,
156-
);
157-
}
158-
}
15964
}

src/lib/models/ContainerReflection.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ export abstract class ContainerReflection extends Reflection {
113113
}
114114
}
115115

116+
override isContainer(): this is ContainerReflection {
117+
return true;
118+
}
119+
116120
override traverse(callback: TraverseCallback) {
117121
for (const child of this.children?.slice() || []) {
118122
if (callback(child, TraverseProperty.Children) === false) {

src/lib/models/Reflection.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { ParameterReflection } from "./ParameterReflection.js";
1111
import type { ReferenceReflection } from "./ReferenceReflection.js";
1212
import type { SignatureReflection } from "./SignatureReflection.js";
1313
import type { TypeParameterReflection } from "./TypeParameterReflection.js";
14+
import type { ContainerReflection } from "./ContainerReflection.js";
1415

1516
/**
1617
* Current reflection id.
@@ -455,6 +456,9 @@ export abstract class Reflection {
455456
isReference(): this is ReferenceReflection {
456457
return this.variant === "reference";
457458
}
459+
isContainer(): this is ContainerReflection {
460+
return false;
461+
}
458462

459463
/**
460464
* Check if this reflection or any of its parents have been marked with the `@deprecated` tag.

src/lib/output/themes/default/templates/hierarchy.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function fullHierarchy(
3737
{context.reflectionIcon(root)}
3838
{root.name}
3939
</a>
40-
{children.length && <ul>{children}</ul>}
40+
{children.length ? <ul>{children}</ul> : null}
4141
</li>
4242
);
4343
}

src/lib/utils-common/array.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,9 @@ export function filterMap<T, U>(
149149
}
150150

151151
export function firstDefined<T, U>(
152-
array: readonly T[] | undefined,
152+
array: readonly T[],
153153
callback: (element: T, index: number) => U | undefined,
154154
): U | undefined {
155-
if (array === undefined) {
156-
return undefined;
157-
}
158-
159155
for (let i = 0; i < array.length; i++) {
160156
const result = callback(array[i], i);
161157
if (result !== undefined) {
@@ -176,17 +172,6 @@ export function aggregate<T>(arr: T[], fn: (item: T) => number) {
176172
return arr.reduce((sum, it) => sum + fn(it), 0);
177173
}
178174

179-
export function aggregateWithJoiner<T>(
180-
arr: T[],
181-
fn: (item: T) => number,
182-
joiner: string,
183-
) {
184-
return (
185-
arr.reduce((sum, it) => sum + fn(it), 0) +
186-
(arr.length - 1) * joiner.length
187-
);
188-
}
189-
190175
export function joinArray<T>(
191176
arr: readonly T[] | undefined,
192177
joiner: string,

src/lib/utils-common/jsx.elements.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ export type JsxChildren =
144144
| JsxElement
145145
| string
146146
| number
147+
| boolean
148+
| bigint
147149
| null
148150
| undefined
149151
| JsxChildren[];

0 commit comments

Comments
 (0)