From 4cd30e390fa48d2a8a0ce32161493ea82c3c7c81 Mon Sep 17 00:00:00 2001
From: Karan Mistry
Date: Wed, 19 Mar 2025 22:05:13 +0530
Subject: [PATCH] fix(material-angular-io): streamline directive and component
metadata handling in dgeni
Currently, docs is not grouped based on Components and Directives. This fix will separate those two sections.
Fixes #24093
---
tools/dgeni/common/decorators.ts | 16 ++++++----
tools/dgeni/common/dgeni-definitions.ts | 15 +++++-----
tools/dgeni/common/directive-metadata.ts | 2 +-
tools/dgeni/common/sort-members.ts | 10 ++-----
tools/dgeni/processors/categorizer.ts | 29 +++++++++++--------
tools/dgeni/processors/entry-point-grouper.ts | 3 ++
tools/dgeni/templates/class.template.html | 17 ++++++++---
.../dgeni/templates/entry-point.template.html | 9 ++++++
tools/dgeni/templates/property.template.html | 12 ++++----
9 files changed, 69 insertions(+), 44 deletions(-)
diff --git a/tools/dgeni/common/decorators.ts b/tools/dgeni/common/decorators.ts
index 5a212003eeea..0b07a9be5f19 100644
--- a/tools/dgeni/common/decorators.ts
+++ b/tools/dgeni/common/decorators.ts
@@ -30,7 +30,11 @@ export function isProperty(doc: MemberDoc): boolean {
}
export function isDirective(doc: ClassExportDoc): boolean {
- return hasClassDecorator(doc, 'Component') || hasClassDecorator(doc, 'Directive');
+ return hasClassDecorator(doc, 'Directive');
+}
+
+export function isComponent(doc: ClassExportDoc): boolean {
+ return hasClassDecorator(doc, 'Component');
}
export function isService(doc: ClassExportDoc): boolean {
@@ -50,12 +54,12 @@ export function isPrimaryExportDoc(doc: ApiDoc): boolean {
return hasJsDocTag(doc, 'docs-primary-export');
}
-export function getDirectiveSelectors(classDoc: CategorizedClassDoc): string[] | undefined {
- if (classDoc.directiveMetadata) {
- const directiveSelectors: string = classDoc.directiveMetadata.get('selector');
+export function getSelectors(classDoc: CategorizedClassDoc): string[] | undefined {
+ if (classDoc.metadata) {
+ const selectors: string = classDoc.metadata.get('selector');
- if (directiveSelectors) {
- return directiveSelectors
+ if (selectors) {
+ return selectors
.replace(/[\r\n]/g, '')
.split(/\s*,\s*/)
.filter(s => s !== '');
diff --git a/tools/dgeni/common/dgeni-definitions.ts b/tools/dgeni/common/dgeni-definitions.ts
index 5b7865b61de4..0da3771dac50 100644
--- a/tools/dgeni/common/dgeni-definitions.ts
+++ b/tools/dgeni/common/dgeni-definitions.ts
@@ -29,12 +29,13 @@ export interface CategorizedClassLikeDoc extends ClassLikeExportDoc, Deprecation
/** Extended Dgeni class document that includes extracted Angular metadata. */
export interface CategorizedClassDoc extends ClassExportDoc, CategorizedClassLikeDoc {
isDirective: boolean;
+ isComponent: boolean;
isService: boolean;
isNgModule: boolean;
isTestHarness: boolean;
- directiveExportAs?: string | null;
- directiveSelectors?: string[];
- directiveMetadata: Map | null;
+ exportAs?: string | null;
+ selectors?: string[];
+ metadata: Map | null;
extendedDoc: ClassLikeExportDoc | undefined;
inheritedDocs: ClassLikeExportDoc[];
}
@@ -42,10 +43,10 @@ export interface CategorizedClassDoc extends ClassExportDoc, CategorizedClassLik
/** Extended Dgeni property-member document that includes extracted Angular metadata. */
export interface CategorizedPropertyMemberDoc extends PropertyMemberDoc, DeprecationInfo {
description: string;
- isDirectiveInput: boolean;
- isDirectiveOutput: boolean;
- directiveInputAlias: string;
- directiveOutputAlias: string;
+ isInput: boolean;
+ isOutput: boolean;
+ inputAlias: string;
+ outputAlias: string;
}
/** Extended Dgeni method-member document that simplifies logic for the Dgeni template. */
diff --git a/tools/dgeni/common/directive-metadata.ts b/tools/dgeni/common/directive-metadata.ts
index 69eb3797297e..f4d3881ac297 100644
--- a/tools/dgeni/common/directive-metadata.ts
+++ b/tools/dgeni/common/directive-metadata.ts
@@ -16,7 +16,7 @@ import {CategorizedClassDoc} from './dgeni-definitions';
* export class MyComponent {}
* ```
*/
-export function getDirectiveMetadata(classDoc: CategorizedClassDoc): Map | null {
+export function getMetadata(classDoc: CategorizedClassDoc): Map | null {
const declaration = classDoc.symbol.valueDeclaration;
const decorators =
declaration && ts.isClassDeclaration(declaration) ? ts.getDecorators(declaration) : null;
diff --git a/tools/dgeni/common/sort-members.ts b/tools/dgeni/common/sort-members.ts
index 656eda962783..f9acca5364c4 100644
--- a/tools/dgeni/common/sort-members.ts
+++ b/tools/dgeni/common/sort-members.ts
@@ -41,17 +41,11 @@ export function sortCategorizedPropertyMembers(
}
// Sort in the order of: Inputs, Outputs, neither
- if (
- (docA.isDirectiveInput && !docB.isDirectiveInput) ||
- (docA.isDirectiveOutput && !docB.isDirectiveInput && !docB.isDirectiveOutput)
- ) {
+ if ((docA.isInput && !docB.isInput) || (docA.isOutput && !docB.isInput && !docB.isOutput)) {
return -1;
}
- if (
- (docB.isDirectiveInput && !docA.isDirectiveInput) ||
- (docB.isDirectiveOutput && !docA.isDirectiveInput && !docA.isDirectiveOutput)
- ) {
+ if ((docB.isInput && !docA.isInput) || (docB.isOutput && !docA.isInput && !docA.isOutput)) {
return 1;
}
diff --git a/tools/dgeni/processors/categorizer.ts b/tools/dgeni/processors/categorizer.ts
index d462e6e178b6..dc6650e14b6e 100644
--- a/tools/dgeni/processors/categorizer.ts
+++ b/tools/dgeni/processors/categorizer.ts
@@ -6,7 +6,8 @@ import {MemberDoc} from 'dgeni-packages/typescript/api-doc-types/MemberDoc';
import {getInheritedDocsOfClass} from '../common/class-inheritance';
import {
decorateDeprecatedDoc,
- getDirectiveSelectors,
+ getSelectors,
+ isComponent,
isDirective,
isMethod,
isNgModule,
@@ -22,7 +23,7 @@ import {
CategorizedPropertyMemberDoc,
CategorizedTypeAliasExportDoc,
} from '../common/dgeni-definitions';
-import {getDirectiveMetadata} from '../common/directive-metadata';
+import {getMetadata} from '../common/directive-metadata';
import {normalizeFunctionParameters} from '../common/normalize-function-parameters';
import {isPublicDoc} from '../common/private-docs';
import {getInputBindingData, getOutputBindingData} from '../common/property-bindings';
@@ -111,7 +112,7 @@ export class Categorizer implements Processor {
// clauses for the Dgeni document. To make the template syntax simpler and more readable,
// store the extended class in a variable.
classDoc.extendedDoc = classDoc.extendsClauses[0] ? classDoc.extendsClauses[0].doc! : undefined;
- classDoc.directiveMetadata = getDirectiveMetadata(classDoc);
+ classDoc.metadata = getMetadata(classDoc);
classDoc.inheritedDocs = getInheritedDocsOfClass(classDoc, this._exportSymbolsToDocsMap);
classDoc.methods.push(
@@ -134,10 +135,14 @@ export class Categorizer implements Processor {
}
// Categorize the current visited classDoc into its Angular type.
- if (isDirective(classDoc) && classDoc.directiveMetadata) {
- classDoc.isDirective = true;
- classDoc.directiveExportAs = classDoc.directiveMetadata.get('exportAs');
- classDoc.directiveSelectors = getDirectiveSelectors(classDoc);
+ if ((isDirective(classDoc) || isComponent(classDoc)) && classDoc.metadata) {
+ if (isComponent(classDoc)) {
+ classDoc.isComponent = true;
+ } else {
+ classDoc.isDirective = true;
+ }
+ classDoc.exportAs = classDoc.metadata.get('exportAs');
+ classDoc.selectors = getSelectors(classDoc);
} else if (isService(classDoc)) {
classDoc.isService = true;
} else if (isNgModule(classDoc)) {
@@ -190,17 +195,17 @@ export class Categorizer implements Processor {
const metadata =
propertyDoc.containerDoc.docType === 'class'
- ? (propertyDoc.containerDoc as CategorizedClassDoc).directiveMetadata
+ ? (propertyDoc.containerDoc as CategorizedClassDoc).metadata
: null;
const inputMetadata = metadata ? getInputBindingData(propertyDoc, metadata) : null;
const outputMetadata = metadata ? getOutputBindingData(propertyDoc, metadata) : null;
- propertyDoc.isDirectiveInput = !!inputMetadata;
- propertyDoc.directiveInputAlias = (inputMetadata && inputMetadata.alias) || '';
+ propertyDoc.isInput = !!inputMetadata;
+ propertyDoc.inputAlias = (inputMetadata && inputMetadata.alias) || '';
- propertyDoc.isDirectiveOutput = !!outputMetadata;
- propertyDoc.directiveOutputAlias = (outputMetadata && outputMetadata.alias) || '';
+ propertyDoc.isOutput = !!outputMetadata;
+ propertyDoc.outputAlias = (outputMetadata && outputMetadata.alias) || '';
}
/**
diff --git a/tools/dgeni/processors/entry-point-grouper.ts b/tools/dgeni/processors/entry-point-grouper.ts
index 84c954c0c57d..678eb906fdca 100644
--- a/tools/dgeni/processors/entry-point-grouper.ts
+++ b/tools/dgeni/processors/entry-point-grouper.ts
@@ -47,6 +47,9 @@ export class EntryPointDoc {
/** List of categorized class docs that are defining a directive. */
directives: CategorizedClassDoc[] = [];
+ /** List of categorized class docs that are defining a directive. */
+ components: CategorizedClassDoc[] = [];
+
/** List of categorized class docs that are defining a service. */
services: CategorizedClassDoc[] = [];
diff --git a/tools/dgeni/templates/class.template.html b/tools/dgeni/templates/class.template.html
index 68538ebcbdd2..c9a4859bfdde 100644
--- a/tools/dgeni/templates/class.template.html
+++ b/tools/dgeni/templates/class.template.html
@@ -17,18 +17,27 @@
{%- endif -%}
-{%- if class.directiveSelectors -%}
+{%- if class.selectors and class.isComponent -%}
+
+ Selector:
+ {% for selector in class.selectors %}
+ {$ selector $}
+ {% endfor %}
+
+{%- endif -%}
+
+{%- if class.selectors and class.isDirective -%}
Selector:
- {% for selector in class.directiveSelectors %}
+ {% for selector in class.selectors %}
{$ selector $}
{% endfor %}
{%- endif -%}
-{%- if class.directiveExportAs -%}
+{%- if class.exportAs -%}
Exported as:
-{$ class.directiveExportAs $}
+{$ class.exportAs $}
{%- endif -%}
{%- if class.isDeprecated -%}
diff --git a/tools/dgeni/templates/entry-point.template.html b/tools/dgeni/templates/entry-point.template.html
index 6b70a5ae16d0..b5437ba42c5b 100644
--- a/tools/dgeni/templates/entry-point.template.html
+++ b/tools/dgeni/templates/entry-point.template.html
@@ -60,6 +60,15 @@