Skip to content

Commit

Permalink
Support nested namespaces
Browse files Browse the repository at this point in the history
Resolves #2582
  • Loading branch information
Gerrit0 committed Jun 1, 2024
1 parent ff65a58 commit 0875618
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 19 deletions.
7 changes: 7 additions & 0 deletions src/lib/converter/comments/discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const variablePropertyKinds = [
ts.SyntaxKind.PropertySignature,
ts.SyntaxKind.BinaryExpression,
ts.SyntaxKind.PropertyAssignment,
ts.SyntaxKind.ShorthandPropertyAssignment,
// class X { constructor(/** Comment */ readonly z: string) }
ts.SyntaxKind.Parameter,
// Variable values
Expand Down Expand Up @@ -43,6 +44,9 @@ const wantedKinds: Record<ReflectionKind, ts.SyntaxKind[]> = {
ts.SyntaxKind.BindingElement,
ts.SyntaxKind.ExportAssignment,
ts.SyntaxKind.PropertyAccessExpression,
ts.SyntaxKind.PropertyDeclaration,
ts.SyntaxKind.PropertyAssignment,
ts.SyntaxKind.ShorthandPropertyAssignment,
],
[ReflectionKind.Enum]: [
ts.SyntaxKind.EnumDeclaration,
Expand All @@ -61,6 +65,9 @@ const wantedKinds: Record<ReflectionKind, ts.SyntaxKind[]> = {
ts.SyntaxKind.VariableDeclaration,
ts.SyntaxKind.ExportAssignment,
ts.SyntaxKind.PropertyAccessExpression,
ts.SyntaxKind.PropertyDeclaration,
ts.SyntaxKind.PropertyAssignment,
ts.SyntaxKind.ShorthandPropertyAssignment,
],
[ReflectionKind.Class]: [
ts.SyntaxKind.ClassDeclaration,
Expand Down
5 changes: 1 addition & 4 deletions src/lib/converter/symbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1007,10 +1007,7 @@ function convertVariableAsNamespace(
context.finalizeDeclarationReflection(reflection);
const rc = context.withScope(reflection);

const declaration = symbol.declarations?.find(ts.isVariableDeclaration);
assert(declaration, "Missing variable declaration");
const type = context.checker.getTypeAtLocation(declaration);

const type = context.checker.getTypeOfSymbol(symbol);
convertSymbols(rc, type.getProperties());

return ts.SymbolFlags.Property;
Expand Down
21 changes: 9 additions & 12 deletions src/lib/models/MediaRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class MediaRegistry {
return this.nextId++;
}

/** Called by {@link ProjectReflection.registerReflection} @internal*/
registerReflection(absolute: string, reflection: Reflection) {
absolute = normalizePath(absolute);
const id = this.registerAbsolute(absolute);
Expand Down Expand Up @@ -106,12 +107,7 @@ export class MediaRegistry {
fromObject(de: Deserializer, obj: JSONMediaRegistry): void {
for (const [key, val] of Object.entries(obj.entries)) {
const absolute = normalizePath(resolve(de.projectRoot, val));
const existingId = this.pathToMedia.get(absolute);
if (existingId) return;

de.oldMediaToNewMedia[+key] = this.nextId;
this.mediaToPath.set(this.nextId, absolute);
this.pathToMedia.set(absolute, this.nextId++);
de.oldMediaToNewMedia[+key] = this.registerAbsolute(absolute);
}

de.defer((project) => {
Expand Down Expand Up @@ -145,9 +141,6 @@ export class ValidatingMediaRegistry extends MediaRegistry {
override fromObject(de: Deserializer, obj: JSONMediaRegistry) {
for (const [key, val] of Object.entries(obj.entries)) {
const absolute = normalizePath(resolve(de.projectRoot, val));
const existingId = this.pathToMedia.get(absolute);
if (existingId) return;

if (!existsSync(absolute)) {
de.logger.warn(
de.logger.i18n.saved_relative_path_0_resolved_from_1_does_not_exist(
Expand All @@ -158,9 +151,7 @@ export class ValidatingMediaRegistry extends MediaRegistry {
continue;
}

de.oldMediaToNewMedia[+key] = this.nextId;
this.mediaToPath.set(this.nextId, absolute);
this.pathToMedia.set(absolute, this.nextId++);
de.oldMediaToNewMedia[+key] = this.registerAbsolute(absolute);
}

de.defer((project) => {
Expand All @@ -173,6 +164,12 @@ export class ValidatingMediaRegistry extends MediaRegistry {
de.oldMediaToNewMedia[+media]!,
refl,
);
} else {
de.logger.warn(
de.logger.i18n.serialized_project_referenced_0_not_part_of_project(
reflId.toString(),
),
);
}
}
});
Expand Down
6 changes: 5 additions & 1 deletion src/lib/models/comments/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export { Comment, CommentTag } from "./comment";
export type { CommentDisplayPart, InlineTagDisplayPart } from "./comment";
export type {
CommentDisplayPart,
InlineTagDisplayPart,
RelativeLinkDisplayPart,
} from "./comment";
22 changes: 22 additions & 0 deletions src/test/converter2/issues/gh2582.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function getApi<T>(Ctor: new () => T) {
return {
/** Member comment */
member: 1,
/** Fn comment */
fn: () => new Ctor(),
};
}

function getAPIs<T1, T2>(Ctor1: new () => T1, Ctor2: new () => T2) {
const a = getApi(Ctor1);

return {
/** A comment @namespace*/
a,
/** B comment @namespace */
b: getApi(Ctor2),
};
}

/** f32 comment @namespace */
export const f32 = getAPIs(Float32Array, Float64Array);
27 changes: 26 additions & 1 deletion src/test/issues.c2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ import {
getConverter2Program,
} from "./programs";
import { TestLogger } from "./TestLogger";
import { getComment, getLinks, getSigComment, query, querySig } from "./utils";
import {
equalKind,
getComment,
getLinks,
getSigComment,
query,
querySig,
} from "./utils";
import { DefaultTheme, PageEvent } from "..";

const base = getConverter2Base();
Expand Down Expand Up @@ -1526,4 +1533,22 @@ describe("Issue Tests", () => {
"Incorrect qualified name",
);
});

it("#2582 nested @namespace", () => {
const project = convert();

equalKind(query(project, "f32"), ReflectionKind.Namespace);
equalKind(query(project, "f32.a"), ReflectionKind.Namespace);
equalKind(query(project, "f32.a.member"), ReflectionKind.Variable);
equalKind(query(project, "f32.a.fn"), ReflectionKind.Function);
equalKind(query(project, "f32.b"), ReflectionKind.Namespace);
equalKind(query(project, "f32.b.member"), ReflectionKind.Reference); // Somewhat odd, but not wrong...
equalKind(query(project, "f32.b.fn"), ReflectionKind.Function);

equal(getComment(project, "f32"), "f32 comment");
equal(getComment(project, "f32.a"), "A comment");
equal(getComment(project, "f32.a.member"), "Member comment");
equal(getComment(project, "f32.a.fn"), "Fn comment");
equal(getComment(project, "f32.b"), "B comment");
});
});
11 changes: 10 additions & 1 deletion src/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import {
DeclarationReflection,
type ProjectReflection,
Reflection,
type ReflectionKind,
ReflectionKind,
type SignatureReflection,
} from "..";
import { filterMap } from "../lib/utils";
import { equal } from "assert/strict";

export function query(
project: ProjectReflection,
Expand Down Expand Up @@ -68,3 +69,11 @@ export function getLinks(refl: Reflection): Array<{
}
});
}

export function equalKind(refl: Reflection, kind: ReflectionKind) {
equal(
refl.kind,
kind,
`Expected ${ReflectionKind[kind]} but got ${ReflectionKind[refl.kind]}`,
);
}

0 comments on commit 0875618

Please sign in to comment.