Skip to content

Commit e0401ec

Browse files
JeanMechethePunderWoman
authored andcommitted
refactor(compiler-cli): extract function overload separatly (angular#56489)
in order for the docs to process function entry, this commit refactor function extraction by keeping the implementation as a the default entry and adds all the overloads into a separate array of entries. fixes angular#56144 PR Close angular#56489
1 parent 6aeda99 commit e0401ec

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

packages/compiler-cli/src/ngtsc/docs/src/extractor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export class DocsExtractor {
154154
private getExportedDeclarations(sourceFile: ts.SourceFile): DeclarationWithExportName[] {
155155
// Use the reflection host to get all the exported declarations from this
156156
// source file entry point.
157-
const reflector = new TypeScriptReflectionHost(this.typeChecker);
157+
const reflector = new TypeScriptReflectionHost(this.typeChecker, false, true);
158158
const exportedDeclarationMap = reflector.getExportsOfModule(sourceFile);
159159

160160
// Augment each declaration with the exported name in the public API.

packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,15 @@ import {isNamedClassDeclaration} from './util';
3131
*/
3232

3333
export class TypeScriptReflectionHost implements ReflectionHost {
34+
/**
35+
* @param skipPrivateValueDeclarationTypes Avoids using a value declaration that is considered private (using a ɵ-prefix),
36+
* instead using the first available declaration. This is needed for the {@link FormControl} API of
37+
* which the type declaration documents the type and the value declaration corresponds with an implementation detail.
38+
*/
3439
constructor(
3540
protected checker: ts.TypeChecker,
3641
private readonly isLocalCompilation = false,
42+
private readonly skipPrivateValueDeclarationTypes = false,
3743
) {}
3844

3945
getDecoratorsOfDeclaration(declaration: DeclarationNode): Decorator[] | null {
@@ -398,9 +404,12 @@ export class TypeScriptReflectionHost implements ReflectionHost {
398404
symbol = this.checker.getAliasedSymbol(symbol);
399405
}
400406

401-
// Look at the resolved Symbol's declarations and pick one of them to return. Value declarations
402-
// are given precedence over type declarations.
403-
if (symbol.valueDeclaration !== undefined) {
407+
// Look at the resolved Symbol's declarations and pick one of them to return.
408+
// Value declarations are given precedence over type declarations if not specified otherwise
409+
if (
410+
symbol.valueDeclaration !== undefined &&
411+
(!this.skipPrivateValueDeclarationTypes || !isPrivateSymbol(this.checker, symbol))
412+
) {
404413
return {
405414
node: symbol.valueDeclaration,
406415
viaModule: this._viaModule(symbol.valueDeclaration, originalId, importInfo),
@@ -781,6 +790,15 @@ function propertyNameToString(node: ts.PropertyName): string | null {
781790
}
782791
}
783792

793+
/** Determines whether a given symbol represents a private API (symbols with names that start with `ɵ`) */
794+
function isPrivateSymbol(typeChecker: ts.TypeChecker, symbol: ts.Symbol) {
795+
if (symbol.valueDeclaration !== undefined) {
796+
const symbolType = typeChecker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);
797+
return symbolType?.symbol?.name.startsWith('ɵ') === true;
798+
}
799+
return false;
800+
}
801+
784802
/**
785803
* Compute the left most identifier in a qualified type chain. E.g. the `a` of `a.b.c.SomeType`.
786804
* @param qualifiedName The starting property access expression from which we want to compute

packages/compiler-cli/test/ngtsc/doc_extraction/doc_extraction_filtering_spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,30 @@ runInEachFileSystem(() => {
4545
const docs: DocEntry[] = env.driveDocsExtraction('index.ts');
4646
expect(docs.length).toBe(0);
4747
});
48+
49+
it('should extract the type declaration if the value declaration is private', () => {
50+
env.write(
51+
'index.ts',
52+
`
53+
/**
54+
* Documented
55+
*/
56+
export interface FormControl<T> {
57+
name: string;
58+
}
59+
export interface ɵFormControlCtor {
60+
new (): FormControl<any>;
61+
}
62+
export const FormControl: ɵFormControlCtor = class FormControl<TValue = any> {
63+
64+
}
65+
`,
66+
);
67+
68+
const docs: DocEntry[] = env.driveDocsExtraction('index.ts');
69+
expect(docs.length).toBe(1);
70+
expect(docs[0].name).toBe('FormControl');
71+
expect(docs[0].rawComment).toMatch(/Documented/);
72+
});
4873
});
4974
});

0 commit comments

Comments
 (0)