Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a failing test to reproduce #2521 #2522

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -45,6 +45,7 @@ markedOptions -> markdownItOptions, markdownItLoader, navigation
### Thanks!

- @HarelM
- @kraenhansen

# Unreleased

Expand Down
3 changes: 3 additions & 0 deletions src/lib/converter/comments/index.ts
Expand Up @@ -31,13 +31,15 @@ const jsDocCommentKinds = [
ts.SyntaxKind.JSDocEnumTag,
];

let commentDiscoveryId = 0;
let commentCache = new WeakMap<ts.SourceFile, Map<number, Comment>>();

// We need to do this for tests so that changing the tsLinkResolution option
// actually works. Without it, we'd get the old parsed comment which doesn't
// have the TS symbols attached.
export function clearCommentCache() {
commentCache = new WeakMap();
commentDiscoveryId = 0;
}

function getCommentWithCache(
Expand Down Expand Up @@ -82,6 +84,7 @@ function getCommentWithCache(
assertNever(ranges[0].kind);
}

comment.discoveryId = ++commentDiscoveryId;
cache.set(ranges[0].pos, comment);
commentCache.set(file, cache);

Expand Down
15 changes: 5 additions & 10 deletions src/lib/converter/factories/signature.ts
@@ -1,7 +1,6 @@
import ts from "typescript";
import assert from "assert";
import {
ConversionFlags,
DeclarationReflection,
IntrinsicType,
ParameterReflection,
Expand Down Expand Up @@ -68,15 +67,11 @@ export function createSignature(
parentReflection = parentReflection.parent;
}

if (
declaration &&
(!parentReflection.comment ||
!(
parentReflection.conversionFlags &
ConversionFlags.VariableOrPropertySource
))
) {
sigRef.comment = context.getSignatureComment(declaration);
if (declaration) {
const sigComment = context.getSignatureComment(declaration);
if (parentReflection.comment?.discoveryId !== sigComment?.discoveryId) {
sigRef.comment = sigComment;
}
}

sigRef.typeParameters = convertTypeParameters(
Expand Down
3 changes: 0 additions & 3 deletions src/lib/converter/symbols.ts
Expand Up @@ -8,7 +8,6 @@ import {
type Reflection,
ReflectionFlag,
ReflectionKind,
ConversionFlags,
} from "../models";
import {
getEnumFlags,
Expand Down Expand Up @@ -697,7 +696,6 @@ function convertProperty(
symbol,
exportSymbol,
);
reflection.conversionFlags |= ConversionFlags.VariableOrPropertySource;

const declaration = symbol.getDeclarations()?.[0];
let parameterType: ts.TypeNode | undefined;
Expand Down Expand Up @@ -1041,7 +1039,6 @@ function convertVariableAsFunction(
exportSymbol,
);
setModifiers(symbol, accessDeclaration, reflection);
reflection.conversionFlags |= ConversionFlags.VariableOrPropertySource;
context.finalizeDeclarationReflection(reflection);

const reflectionContext = context.withScope(reflection);
Expand Down
15 changes: 14 additions & 1 deletion src/lib/models/comments/comment.ts
Expand Up @@ -4,6 +4,7 @@ import { ReflectionKind } from "../reflections/kind";
import { ReflectionSymbolId } from "../reflections/ReflectionSymbolId";

import type { Serializer, Deserializer, JSONOutput } from "../../serialization";
import { NonEnumerable } from "../../utils/general";

/**
* Represents a parsed piece of a comment.
Expand Down Expand Up @@ -394,6 +395,14 @@ export class Comment {
*/
label?: string;

/**
* Internal discovery ID used to prevent symbol comments from
* being duplicated on signatures. Only set when the comment was created
* @internal
*/
@NonEnumerable
discoveryId?: number;

/**
* Creates a new Comment instance.
*/
Expand All @@ -412,11 +421,15 @@ export class Comment {
* Create a deep clone of this comment.
*/
clone() {
return new Comment(
const comment = new Comment(
Comment.cloneDisplayParts(this.summary),
this.blockTags.map((tag) => tag.clone()),
new Set(this.modifierTags),
);
if (this.discoveryId) {
comment.discoveryId = this.discoveryId;
}
return comment;
}

/**
Expand Down
14 changes: 0 additions & 14 deletions src/lib/models/reflections/declaration.ts
Expand Up @@ -37,14 +37,6 @@ export interface DeclarationHierarchy {
isTarget?: boolean;
}

/**
* @internal
*/
export enum ConversionFlags {
None = 0,
VariableOrPropertySource = 1,
}

/**
* A reflection that represents a single declaration emitted by the TypeScript compiler.
*
Expand Down Expand Up @@ -172,12 +164,6 @@ export class DeclarationReflection extends ContainerReflection {
*/
packageVersion?: string;

/**
* Flags for information about a reflection which is needed solely during conversion.
* @internal
*/
conversionFlags = ConversionFlags.None;

override isDeclaration(): this is DeclarationReflection {
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/models/reflections/index.ts
Expand Up @@ -6,7 +6,7 @@ export {
} from "./abstract";
export type { TraverseCallback, ReflectionVisitor } from "./abstract";
export { ContainerReflection } from "./container";
export { DeclarationReflection, ConversionFlags } from "./declaration";
export { DeclarationReflection } from "./declaration";
export type { DeclarationHierarchy } from "./declaration";
export { ReflectionKind } from "./kind";
export { ParameterReflection } from "./parameter";
Expand Down
4 changes: 2 additions & 2 deletions src/test/converter/js/index.js
Expand Up @@ -47,8 +47,8 @@

/**
* @callback Foo
* @param {...string} args
* @returns {number}
* @param {...string} args Foo param description
* @returns {number} Foo return description
*/

/** @type {Foo} */
Expand Down
30 changes: 30 additions & 0 deletions src/test/converter/js/specs.json
Expand Up @@ -383,6 +383,14 @@
"flags": {
"isRest": true
},
"comment": {
"summary": [
{
"kind": "text",
"text": "Foo param description"
}
]
},
"type": {
"type": "array",
"elementType": {
Expand Down Expand Up @@ -902,6 +910,20 @@
"variant": "signature",
"kind": 4096,
"flags": {},
"comment": {
"summary": [],
"blockTags": [
{
"tag": "@returns",
"content": [
{
"kind": "text",
"text": "Foo return description"
}
]
}
]
},
"sources": [
{
"fileName": "index.js",
Expand All @@ -919,6 +941,14 @@
"flags": {
"isRest": true
},
"comment": {
"summary": [
{
"kind": "text",
"text": "Foo param description"
}
]
},
"type": {
"type": "array",
"elementType": {
Expand Down
18 changes: 18 additions & 0 deletions src/test/converter2/issues/gh2521.d.ts
@@ -0,0 +1,18 @@
/**
* Original comment.
*/
export interface Foo {
/** Overload 1 */
(): void;
/** Overload 2 */
(baz: number): void;
}

// Inherits overload comments, but not Foo comment
// Foo comment could be inherited with {@inheritDoc Foo}
export const fooWithoutComment: Foo;

/**
* New comment.
*/
export const fooWithComment: Foo;
18 changes: 15 additions & 3 deletions src/test/issues.c2.test.ts
Expand Up @@ -27,7 +27,7 @@ import {
getConverter2Program,
} from "./programs";
import { TestLogger } from "./TestLogger";
import { getComment, getLinks, query, querySig } from "./utils";
import { getComment, getLinks, getSigComment, query, querySig } from "./utils";
import { DefaultTheme, PageEvent } from "..";

const base = getConverter2Base();
Expand Down Expand Up @@ -891,9 +891,9 @@ describe("Issue Tests", () => {
const project = convert();
for (const [name, docs, sigDocs] of [
["built", "", "inner docs"],
["built2", "outer docs", ""],
["built2", "outer docs", "inner docs"],
["fn", "", "inner docs"],
["fn2", "outer docs", ""],
["fn2", "outer docs", "inner docs"],
]) {
const refl = query(project, name);
ok(refl.signatures?.[0]);
Expand Down Expand Up @@ -1467,6 +1467,18 @@ describe("Issue Tests", () => {
equal(cb2.type.declaration.signatures![0].comment, undefined);
});

it("Specifying comment on variable still inherits signature comments, #2521", () => {
const project = convert();

equal(getComment(project, "fooWithoutComment"), "");
equal(getSigComment(project, "fooWithoutComment", 0), "Overload 1");
equal(getSigComment(project, "fooWithoutComment", 1), "Overload 2");

equal(getComment(project, "fooWithComment"), "New comment.");
equal(getSigComment(project, "fooWithComment", 0), "Overload 1");
equal(getSigComment(project, "fooWithComment", 1), "Overload 2");
});

it("Ignores @license and @import comments at the top of the file, #2552", () => {
const project = convert();
equal(
Expand Down
10 changes: 10 additions & 0 deletions src/test/utils.ts
Expand Up @@ -35,6 +35,16 @@ export function getComment(project: ProjectReflection, name: string) {
return Comment.combineDisplayParts(query(project, name).comment?.summary);
}

export function getSigComment(
project: ProjectReflection,
name: string,
index = 0,
) {
return Comment.combineDisplayParts(
querySig(project, name, index).comment?.summary,
);
}

export function getLinks(refl: Reflection): Array<{
display: string;
target: undefined | string | [ReflectionKind, string];
Expand Down