mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
refactor(compiler-cli): support ignoring specific doc entries during extraction (#55053)
This commit adds support for ignoring specific doc entries when extracting doc entries. This allows us to drop e.g. `InputFunction` from the API docs, given that the `input` API entry holds all the relevant information. `InputFunction` only exists for type purposes in the `.d.ts`. PR Close #55053
This commit is contained in:
parent
b63afb9e93
commit
ee76001431
5 changed files with 92 additions and 6 deletions
|
|
@ -42,10 +42,12 @@ export class DocsExtractor {
|
|||
const exportedDeclarations = this.getExportedDeclarations(sourceFile);
|
||||
for (const [exportName, node] of exportedDeclarations) {
|
||||
// Skip any symbols with an Angular-internal name.
|
||||
if (isAngularPrivateName(exportName)) continue;
|
||||
if (isAngularPrivateName(exportName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const entry = this.extractDeclaration(node);
|
||||
if (entry) {
|
||||
if (entry && !isIgnoredDocEntry(entry)) {
|
||||
// The exported name of an API may be different from its declaration name, so
|
||||
// use the declaration name.
|
||||
entries.push({...entry, name: exportName});
|
||||
|
|
@ -77,10 +79,8 @@ export class DocsExtractor {
|
|||
}
|
||||
|
||||
if (ts.isVariableDeclaration(node) && !isSyntheticAngularConstant(node)) {
|
||||
if (isDecoratorDeclaration(node)) {
|
||||
return extractorDecorator(node, this.typeChecker);
|
||||
}
|
||||
return extractConstant(node, this.typeChecker);
|
||||
return isDecoratorDeclaration(node) ? extractorDecorator(node, this.typeChecker) :
|
||||
extractConstant(node, this.typeChecker);
|
||||
}
|
||||
|
||||
if (ts.isTypeAliasDeclaration(node)) {
|
||||
|
|
@ -138,3 +138,22 @@ function isIgnoredInterface(node: ts.InterfaceDeclaration) {
|
|||
// that contain the decorator options.
|
||||
return node.name.getText().endsWith('Decorator') || isDecoratorOptionsInterface(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the doc entry should be ignored.
|
||||
*
|
||||
* Note: We cannot check whether a node is marked as docs private
|
||||
* before extraction because the extractor may find the attached
|
||||
* JSDoc tags on different AST nodes. For example, a variable declaration
|
||||
* never has JSDoc tags attached, but rather the parent variable statement.
|
||||
*/
|
||||
function isIgnoredDocEntry(entry: DocEntry): boolean {
|
||||
const isDocsPrivate = entry.jsdocTags.find(e => e.name === 'docsPrivate');
|
||||
if (isDocsPrivate !== undefined && isDocsPrivate.comment === '') {
|
||||
throw new Error(
|
||||
`Docs extraction: Entry "${entry.name}" is marked as ` +
|
||||
`"@docsPrivate" but without reasoning.`);
|
||||
}
|
||||
|
||||
return isDocsPrivate !== undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {DocEntry} from '@angular/compiler-cli/src/ngtsc/docs/src/entities';
|
||||
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
||||
|
||||
import {NgtscTestEnvironment} from '../env';
|
||||
|
||||
runInEachFileSystem(() => {
|
||||
describe('ngtsc docs: @docsPrivate tag', () => {
|
||||
let env: NgtscTestEnvironment;
|
||||
|
||||
beforeEach(() => {
|
||||
env = NgtscTestEnvironment.setup({});
|
||||
env.tsconfig();
|
||||
});
|
||||
|
||||
function test(input: string): DocEntry[] {
|
||||
env.write('index.ts', input);
|
||||
return env.driveDocsExtraction('index.ts');
|
||||
}
|
||||
|
||||
it('should omit constant annotated with `@docsPrivate`', () => {
|
||||
expect(test(`
|
||||
/** @docsPrivate <reason> */
|
||||
export const bla = true;
|
||||
`)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should omit class annotated with `@docsPrivate`', () => {
|
||||
expect(test(`
|
||||
/** @docsPrivate <reason> */
|
||||
export class Bla {}
|
||||
`)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should omit function annotated with `@docsPrivate`', () => {
|
||||
expect(test(`
|
||||
/** @docsPrivate <reason> */
|
||||
export function bla() {};
|
||||
`)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should omit interface annotated with `@docsPrivate`', () => {
|
||||
expect(test(`
|
||||
/** @docsPrivate <reason> */
|
||||
export interface BlaFunction {}
|
||||
`)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should error if marked as private without reasoning', () => {
|
||||
expect(() => test(`
|
||||
/** @docsPrivate */
|
||||
export interface BlaFunction {}
|
||||
`)).toThrowError(/Entry "BlaFunction" is marked as "@docsPrivate" but without reasoning./);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -32,6 +32,7 @@ export function inputRequiredFunction<ReadT, WriteT = ReadT>(opts?: InputOptions
|
|||
* `input.required` function.
|
||||
*
|
||||
* @developerPreview
|
||||
* @docsPrivate Ignored because `input` is the canonical API entry.
|
||||
*/
|
||||
export interface InputFunction {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ export function modelRequiredFunction<T>(): ModelSignal<T> {
|
|||
* `model.required` function.
|
||||
*
|
||||
* @developerPreview
|
||||
* @docsPrivate Ignored because `model` is the canonical API entry.
|
||||
*/
|
||||
export interface ModelFunction {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ function viewChildRequiredFn<LocatorT, ReadT>(
|
|||
* property.
|
||||
*
|
||||
* @developerPreview
|
||||
* @docsPrivate Ignored because `viewChild` is the canonical API entry.
|
||||
*/
|
||||
export interface ViewChildFunction {
|
||||
/**
|
||||
|
|
@ -140,6 +141,7 @@ function contentChildRequiredFn<LocatorT, ReadT>(
|
|||
* provides access to required query results via the `.required` property.
|
||||
*
|
||||
* @developerPreview
|
||||
* @docsPrivate Ignored because `contentChild` is the canonical API entry.
|
||||
*/
|
||||
export interface ContentChildFunction {
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue