Skip to content

fix(material-angular-io): streamline directive and component metadata handling in dgeni #30655

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

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions tools/dgeni/common/decorators.ts
Original file line number Diff line number Diff line change
@@ -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 !== '');
15 changes: 8 additions & 7 deletions tools/dgeni/common/dgeni-definitions.ts
Original file line number Diff line number Diff line change
@@ -29,23 +29,24 @@ 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<string, any> | null;
exportAs?: string | null;
selectors?: string[];
metadata: Map<string, any> | null;
extendedDoc: ClassLikeExportDoc | undefined;
inheritedDocs: ClassLikeExportDoc[];
}

/** 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. */
2 changes: 1 addition & 1 deletion tools/dgeni/common/directive-metadata.ts
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ import {CategorizedClassDoc} from './dgeni-definitions';
* export class MyComponent {}
* ```
*/
export function getDirectiveMetadata(classDoc: CategorizedClassDoc): Map<string, any> | null {
export function getMetadata(classDoc: CategorizedClassDoc): Map<string, any> | null {
const declaration = classDoc.symbol.valueDeclaration;
const decorators =
declaration && ts.isClassDeclaration(declaration) ? ts.getDecorators(declaration) : null;
10 changes: 2 additions & 8 deletions tools/dgeni/common/sort-members.ts
Original file line number Diff line number Diff line change
@@ -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;
}

29 changes: 17 additions & 12 deletions tools/dgeni/processors/categorizer.ts
Original file line number Diff line number Diff line change
@@ -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) || '';
}

/**
3 changes: 3 additions & 0 deletions tools/dgeni/processors/entry-point-grouper.ts
Original file line number Diff line number Diff line change
@@ -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[] = [];

17 changes: 13 additions & 4 deletions tools/dgeni/templates/class.template.html
Original file line number Diff line number Diff line change
@@ -17,18 +17,27 @@ <h4 id="{$ class.name $}" class="docs-header-link docs-api-h4 docs-api-class-nam
<p class="docs-api-class-description">{$ class.description | marked | safe $}</p>
{%- endif -%}

{%- if class.directiveSelectors -%}
{%- if class.selectors and class.isComponent -%}
<p class="docs-api-component-selectors">
<span class="docs-api-class-selector-label">Selector:</span>
{% for selector in class.selectors %}
<span class="docs-api-class-selector-name">{$ selector $}</span>
{% endfor %}
</p>
{%- endif -%}

{%- if class.selectors and class.isDirective -%}
<p class="docs-api-directive-selectors">
<span class="docs-api-class-selector-label">Selector:</span>
{% for selector in class.directiveSelectors %}
{% for selector in class.selectors %}
<span class="docs-api-class-selector-name">{$ selector $}</span>
{% endfor %}
</p>
{%- endif -%}

{%- if class.directiveExportAs -%}
{%- if class.exportAs -%}
<span class="docs-api-class-export-label">Exported as:</span>
<span class="docs-api-class-export-name">{$ class.directiveExportAs $}</span>
<span class="docs-api-class-export-name">{$ class.exportAs $}</span>
{%- endif -%}

{%- if class.isDeprecated -%}
9 changes: 9 additions & 0 deletions tools/dgeni/templates/entry-point.template.html
Original file line number Diff line number Diff line change
@@ -60,6 +60,15 @@ <h3 id="{$ doc.name $}-services" class="docs-header-link docs-api-h3">
{% endfor %}
{%- endif -%}

{%- if doc.components.length -%}
<h3 id="{$ doc.name $}-components" class="docs-header-link docs-api-h3">
<span header-link="components"></span>
Components
</h3>
{% for component in doc.components %}
{$ class(component) $}
{% endfor %}
{%- endif -%}

{%- if doc.directives.length -%}
<h3 id="{$ doc.name $}-directives" class="docs-header-link docs-api-h3">
12 changes: 6 additions & 6 deletions tools/dgeni/templates/property.template.html
Original file line number Diff line number Diff line change
@@ -2,19 +2,19 @@

<tr class="docs-api-properties-row">
<td class="docs-api-properties-name-cell">
{%- if property.isDirectiveInput -%}
{%- if property.isInput -%}
<div class="docs-api-input-marker">
{%- if property.directiveInputAlias -%}
@Input(<span class="docs-api-input-alias">{$ property.directiveInputAlias $}</span>)
{%- if property.inputAlias -%}
@Input(<span class="docs-api-input-alias">{$ property.inputAlias $}</span>)
{% else %}
@Input()
{%- endif -%}
</div>
{%- endif -%}
{%- if property.isDirectiveOutput -%}
{%- if property.isOutput -%}
<div class="docs-api-output-marker">
{%- if property.directiveOutputAlias -%}
@Output(<span class="docs-api-output-alias">{$ property.directiveOutputAlias $}</span>)
{%- if property.outputAlias -%}
@Output(<span class="docs-api-output-alias">{$ property.outputAlias $}</span>)
{% else %}
@Output()
{%- endif -%}
Loading