Skip to content

Commit

Permalink
refactor(api-gen): add deprecation message and usage notes in class m…
Browse files Browse the repository at this point in the history
…embers (#1955)

As reported by angular/angular#55196

PR Close #1955
  • Loading branch information
JeanMeche authored and josephperrott committed Apr 8, 2024
1 parent d696fac commit 479413e
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 29 deletions.
4 changes: 4 additions & 0 deletions bazel/api-gen/rendering/entities/categorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ export function isDeprecatedEntry<T extends HasJsDocTags>(entry: T) {
return entry.jsdocTags.some((tag) => tag.name === 'deprecated');
}

export function getDeprecatedEntry<T extends HasJsDocTags>(entry: T) {
return entry.jsdocTags.find((tag) => tag.name === 'deprecated')?.comment ?? null;
}

/** Gets whether the given entry is developer preview. */
export function isDeveloperPreview<T extends HasJsDocTags>(entry: T) {
return entry.jsdocTags.some((tag) => tag.name === 'developerPreview');
Expand Down
5 changes: 3 additions & 2 deletions bazel/api-gen/rendering/entities/renderables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,15 @@ export type FunctionEntryRenderable = FunctionEntry &
DocEntryRenderable & {
codeLinesGroups: Map<string, CodeLineRenderable[]>;
params: ParameterEntryRenderable[];
isDeprecated: boolean;
deprecationMessage: string | null;
};

/** Sub-entry for a single class or enum member augmented with transformed content for rendering. */
export interface MemberEntryRenderable extends MemberEntry {
htmlDescription: string;
jsdocTags: JsDocTagRenderable[];
isDeprecated: boolean;
deprecationMessage: string | null;
htmlUsageNotes: string;
}

/** Sub-entry for a class method augmented transformed content for rendering. */
Expand Down
1 change: 1 addition & 0 deletions bazel/api-gen/rendering/entities/traits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export interface HasRenderableParams {

export interface HasDeprecatedFlag {
isDeprecated: boolean;
deprecationMessage: string | null;
}

export interface HasDeveloperPreviewFlag {
Expand Down
14 changes: 7 additions & 7 deletions bazel/api-gen/rendering/templates/class-member.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {h, Fragment} from 'preact';
import {MemberEntryRenderable} from '../entities/renderables';
import {ClassMethodInfo} from './class-method-info';
import {RawHtml} from './raw-html';
import {Fragment, h} from 'preact';
import {
isClassMethodEntry,
isGetterEntry,
isPropertyEntry,
isSetterEntry,
} from '../entities/categorization';
import {DeprecatedLabel} from './deprecated-label';
import {MemberEntryRenderable} from '../entities/renderables';
import {
REFERENCE_HEADER,
REFERENCE_MEMBER_CARD,
REFERENCE_MEMBER_CARD_BODY,
REFERENCE_MEMBER_CARD_ITEM,
REFERENCE_HEADER,
} from '../styling/css-classes';
import {ClassMethodInfo} from './class-method-info';
import {DeprecatedLabel} from './deprecated-label';
import {RawHtml} from './raw-html';

export function ClassMember(props: {members: MemberEntryRenderable[]}) {
const memberName = props.members[0].name;
Expand Down Expand Up @@ -62,7 +62,7 @@ export function ClassMember(props: {members: MemberEntryRenderable[]}) {
)}
</div>
</div>
{props.members.every((member) => member.isDeprecated) ? (
{props.members.every((member) => member.deprecationMessage !== null) ? (
<DeprecatedLabel entry={props.members[0]} />
) : (
<></>
Expand Down
44 changes: 33 additions & 11 deletions bazel/api-gen/rendering/templates/class-method-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,54 @@
*/

import {Fragment, h} from 'preact';
import {PARAM_KEYWORD_CLASS_NAME, REFERENCE_MEMBER_CARD_ITEM} from '../styling/css-classes';
import {
FunctionEntryRenderable,
MethodEntryRenderable,
ParameterEntryRenderable
ParameterEntryRenderable,
} from '../entities/renderables';
import {PARAM_KEYWORD_CLASS_NAME, REFERENCE_MEMBER_CARD_ITEM} from '../styling/css-classes';
import {DeprecatedLabel} from './deprecated-label';
import {Parameter} from './parameter';
import {RawHtml} from './raw-html';

/**
* Component to render the method-specific parts of a class's API reference.
*/
export function ClassMethodInfo(props: { entry: MethodEntryRenderable | FunctionEntryRenderable, isOverloaded?: boolean }) {
export function ClassMethodInfo(props: {
entry: MethodEntryRenderable | FunctionEntryRenderable;
isOverloaded?: boolean;
}) {
const entry = props.entry;

return (
<div className={`${REFERENCE_MEMBER_CARD_ITEM} ${entry.isDeprecated ? 'docs-reference-card-item-deprecated' : ''}`}>
<RawHtml value={entry.htmlDescription} className={'docs-function-definition'} />
{/* In case when method is overloaded we need to indicate which overload is deprecated */}
{!props.isOverloaded ? <></> : <DeprecatedLabel entry={entry}/>}
{entry.params.map((param: ParameterEntryRenderable) => <Parameter param={param}/>)}
<div className={'docs-return-type'}>
<span className={PARAM_KEYWORD_CLASS_NAME}>@returns</span>
<code>{entry.returnType}</code>
<div
className={`${REFERENCE_MEMBER_CARD_ITEM} ${entry.isDeprecated ? 'docs-reference-card-item-deprecated' : ''}`}
>
<RawHtml value={entry.htmlDescription} className={'docs-function-definition'} />
{/* In case when method is overloaded we need to indicate which overload is deprecated */}
{!props.isOverloaded ? (
<></>
) : (
<div>
<DeprecatedLabel entry={entry} />
<span>{entry.deprecationMessage}</span>
</div>
)}
{entry.params.map((param: ParameterEntryRenderable) => (
<Parameter param={param} />
))}
<div className={'docs-return-type'}>
<span className={PARAM_KEYWORD_CLASS_NAME}>@returns</span>
<code>{entry.returnType}</code>
</div>
{entry.htmlUsageNotes ? (
<div className={'docs-usage-notes'}>
<span className={PARAM_KEYWORD_CLASS_NAME}>Usage notes</span>
<RawHtml value={entry.htmlUsageNotes} />
</div>
) : (
<></>
)}
</div>
);
}
17 changes: 13 additions & 4 deletions bazel/api-gen/rendering/templates/deprecated-label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@
import {Fragment, h} from 'preact';
import {PARAM_KEYWORD_CLASS_NAME} from '../styling/css-classes';

export function DeprecatedLabel(props: {entry: {isDeprecated: boolean}}) {
export function DeprecatedLabel(props: {
entry: {isDeprecated: boolean} | {deprecationMessage: string | null};
}) {
const entry = props.entry;

if (entry.isDeprecated) {
return (<span className={`${PARAM_KEYWORD_CLASS_NAME} docs-deprecated`}>@deprecated</span>);
if ('isDeprecated' in entry) {
return <span className={`${PARAM_KEYWORD_CLASS_NAME} docs-deprecated`}>@deprecated</span>;
} else if ('deprecationMessage' in entry && entry.deprecationMessage !== null) {
return (
<div>
<span className={`${PARAM_KEYWORD_CLASS_NAME} docs-deprecated`}>@deprecated</span>
<span>{entry.deprecationMessage}</span>
</div>
);
}

return (<></>);
return <></>;
}
9 changes: 7 additions & 2 deletions bazel/api-gen/rendering/transforms/jsdoc-transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {JsDocTagEntry} from '../entities';
import {marked} from 'marked';
import {JsDocTagEntry} from '../entities';

import {rewriteLinks} from '../backwards-compatibility/links-mapper';
import {isDeprecatedEntry, isDeveloperPreview} from '../entities/categorization';
import {
getDeprecatedEntry,
isDeprecatedEntry,
isDeveloperPreview,
} from '../entities/categorization';
import {LinkEntryRenderable} from '../entities/renderables';
import {
HasAdditionalLinks,
Expand Down Expand Up @@ -104,6 +108,7 @@ export function setEntryFlags<T extends HasJsDocTags>(
return {
...entry,
isDeprecated: isDeprecatedEntry(entry),
deprecationMessage: getDeprecatedEntry(entry),
isDeveloperPreview: isDeveloperPreview(entry),
};
}
Expand Down
17 changes: 14 additions & 3 deletions bazel/api-gen/rendering/transforms/member-transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import {isClassMethodEntry} from '../entities/categorization';
import {MemberEntryRenderable} from '../entities/renderables';
import {HasMembers, HasRenderableMembers, HasRenderableMembersGroups} from '../entities/traits';

import {addHtmlDescription, addHtmlJsDocTagComments, setEntryFlags} from './jsdoc-transforms';
import {
addHtmlDescription,
addHtmlJsDocTagComments,
addHtmlUsageNotes,
setEntryFlags,
} from './jsdoc-transforms';

const lifecycleMethods = [
'ngAfterContentChecked',
Expand Down Expand Up @@ -66,7 +71,9 @@ export function addRenderableGroupMembers<T extends HasMembers>(

const membersGroups = members.reduce((groups, item) => {
const member = setEntryFlags(
addMethodParamsDescription(addHtmlDescription(addHtmlJsDocTagComments(item))),
addMethodParamsDescription(
addHtmlDescription(addHtmlUsageNotes(addHtmlJsDocTagComments(item))),
),
);
if (groups.has(member.name)) {
const group = groups.get(member.name);
Expand All @@ -85,7 +92,11 @@ export function addRenderableGroupMembers<T extends HasMembers>(

export function addRenderableMembers<T extends HasMembers>(entry: T): T & HasRenderableMembers {
const members = entry.members.map((entry) =>
setEntryFlags(addMethodParamsDescription(addHtmlDescription(addHtmlJsDocTagComments(entry)))),
setEntryFlags(
addMethodParamsDescription(
addHtmlDescription(addHtmlUsageNotes(addHtmlJsDocTagComments(entry))),
),
),
);

return {
Expand Down

0 comments on commit 479413e

Please sign in to comment.