Skip to content

Commit

Permalink
feat(ngdoc): hide component and property when add private or internal…
Browse files Browse the repository at this point in the history
… and rewrite directive name for name tag
  • Loading branch information
why520crazy committed Aug 1, 2022
1 parent 3bd92ab commit 41a15a1
Show file tree
Hide file tree
Showing 19 changed files with 474 additions and 59 deletions.
1 change: 1 addition & 0 deletions packages/a-lib/button/button.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, OnInit, HostBinding, Input, ElementRef, Output, EventEmitter

/**
* General Button Component description.
* @name alib-button
*/
@Component({
selector: 'alib-button,[alibButton]',
Expand Down
52 changes: 34 additions & 18 deletions packages/ngdoc/src/ng-parser-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ export interface DefaultNgParserHostOptions {
rootDir?: string;
watch?: boolean;
watcher?: (event: string, filename: string) => void;
fsHost?: {
fileExists: (path: string) => boolean;
readFile: (path: string) => string;
writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => void;
readDirectory: (
rootDir: string,
extensions: readonly string[],
excludes: readonly string[] | undefined,
includes: readonly string[],
depth?: number
) => readonly string[];
};
}

export class DefaultNgParserHost implements NgParserHost {
Expand Down Expand Up @@ -50,23 +62,33 @@ export class DefaultNgParserHost implements NgParserHost {
}

private initialize() {
if (this.options.tsConfigPath) {
const parsedResult = ts.getParsedCommandLineOfConfigFile(this.options.tsConfigPath, undefined, {
useCaseSensitiveFileNames: true,
if (!this.options.fsHost) {
this.options.fsHost = {
fileExists: path => {
return ts.sys.fileExists(path);
},
readFile: path => {
return ts.sys.readFile(path);
},
writeFile: (fileName, content) => {
return ts.sys.writeFile(fileName, content);
},
readDirectory: (path, extensions, excludes, includes, depth) => {
return ts.sys.readDirectory(path, extensions, excludes, includes, depth);
}
};
}
if (this.options.tsConfigPath) {
const parsedResult = ts.getParsedCommandLineOfConfigFile(this.options.tsConfigPath, undefined, {
useCaseSensitiveFileNames: true,
fileExists: this.options.fsHost.fileExists,
readFile: this.options.fsHost.readFile,
getCurrentDirectory: () => {
const currentDirectory = ts.sys.getCurrentDirectory();
debug(`getParsedCommandLineOfConfigFile currentDirectory is ${currentDirectory}`, 'ng-parser');
return currentDirectory;
},
readDirectory: (path, extensions, excludes, includes, depth) => {
return ts.sys.readDirectory(path, extensions, excludes, includes, depth);
},
readDirectory: this.options.fsHost.readDirectory,
onUnRecoverableConfigFileDiagnostic: () => {}
});
if (parsedResult) {
Expand Down Expand Up @@ -128,17 +150,15 @@ export class DefaultNgParserHost implements NgParserHost {

private getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void) {
this.readFiles.push(fileName);
const sourceText = ts.sys.readFile(fileName);
const sourceText = this.options.fsHost.readFile(fileName);
return sourceText !== undefined ? ts.createSourceFile(fileName, sourceText, languageVersion) : undefined;
}

private createCompilerHost(): ts.CompilerHost {
return {
getSourceFile: this.getSourceFile.bind(this),
getDefaultLibFileName: () => '',
writeFile: (fileName, content) => {
return ts.sys.writeFile(fileName, content);
},
writeFile: this.options.fsHost.writeFile,
getCurrentDirectory: () => {
const result = ts.sys.getCurrentDirectory();
debug(`createCompilerHost currentDirectory is ${result}`, 'ng-parser');
Expand All @@ -152,12 +172,8 @@ export class DefaultNgParserHost implements NgParserHost {
useCaseSensitiveFileNames: () => {
return ts.sys.useCaseSensitiveFileNames;
},
fileExists: filename => {
return ts.sys.fileExists(filename);
},
readFile: filename => {
return ts.sys.readFile(filename);
},
fileExists: this.options.fsHost.fileExists,
readFile: this.options.fsHost.readFile,
resolveModuleNames: this.resolveModuleNames.bind(this),
directoryExists: dirPath => {
return ts.sys.directoryExists(dirPath);
Expand All @@ -170,8 +186,8 @@ export class DefaultNgParserHost implements NgParserHost {
for (const moduleName of moduleNames) {
// try to use standard resolution
const result = ts.resolveModuleName(moduleName, containingFile, this.compileOptions, {
fileExists: ts.sys.fileExists,
readFile: ts.sys.readFile
fileExists: this.options.fsHost.fileExists,
readFile: this.options.fsHost.readFile
});
if (result.resolvedModule) {
this.allResolvedModules.push(result.resolvedModule);
Expand Down
2 changes: 1 addition & 1 deletion packages/ngdoc/src/ng-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { toolkit } from '@docgeni/toolkit';
import { Project, Node } from 'ts-morph';
import ts from 'typescript';

const EXCLUDE_DIRS = [];
const EXCLUDE_DIRS: string[] = [];
const ONLY_TEST_FIXTURE = 'full';
const ROOT_FIXTURES = path.resolve(__dirname, '../test/fixtures');

Expand Down
59 changes: 35 additions & 24 deletions packages/ngdoc/src/ng-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
getDocTagsBySymbol,
getDocTagsBySignature,
serializeMethodParameterSymbol,
declarationIsPublic
declarationIsPublic,
isPublicTag,
DocTagResult
} from './parser';
import { createNgParserHost, NgParserHost } from './ng-parser-host';

Expand Down Expand Up @@ -89,12 +91,12 @@ export class NgDocParser {
const ngDecorator = getNgDecorator(symbol.valueDeclaration);
if (ngDecorator) {
const type = getNgDocItemType(ngDecorator.name);
const tags = getDocTagsBySymbol(symbol) as { private: ts.JSDocTagInfo };
if (!tags.private) {
const tags = getDocTagsBySymbol(symbol);
if (isPublicTag(tags)) {
switch (type) {
case 'component':
case 'directive':
docs.push(this.parseDirectiveDoc(context, type, symbol, ngDecorator));
docs.push(this.parseDirectiveDoc(context, type, symbol, ngDecorator, tags));
break;
case 'service':
docs.push(this.parseServiceDoc(context, symbol, ngDecorator));
Expand Down Expand Up @@ -125,11 +127,18 @@ export class NgDocParser {
return directiveDoc;
}

private parseDirectiveDoc(context: ParserSourceFileContext, type: NgDocItemType, symbol: ts.Symbol, ngDecorator: NgParsedDecorator) {
private parseDirectiveDoc(
context: ParserSourceFileContext,
type: NgDocItemType,
symbol: ts.Symbol,
ngDecorator: NgParsedDecorator,
tags: DocTagResult
) {
const description = serializeSymbol(symbol, context.checker);
const directiveDoc: NgDirectiveDoc = {
type: type,
name: description.name,
name: tags.name ? tags.name.text : description.name,
className: description.name,
description: description.comment,
...getDirectiveMeta(ngDecorator.argumentInfo)
};
Expand All @@ -149,25 +158,27 @@ export class NgDocParser {
const options = getNgPropertyOptions(propertyDeclaration, context.checker);
const propertyKind = getPropertyKind(decorator.name);
const tags = getDocTagsBySymbol(symbol);
const property: NgPropertyDoc = {
kind: propertyKind,
name: symbolDescription.name,
aliasName: this.getNgPropertyAliasName(decorator),
type: {
name: symbolDescription.type,
options: options,
kindName: ts.SyntaxKind[propertyDeclaration.type?.kind]
},
description: tags.description && tags.description.text ? tags.description.text : symbolDescription.comment,
default: '',
tags: tags
};

if (propertyKind === 'Input') {
property.default =
(tags.default && tags.default.text) || getPropertyValue(propertyDeclaration, symbolDescription.type);
if (isPublicTag(tags)) {
const property: NgPropertyDoc = {
kind: propertyKind,
name: symbolDescription.name,
aliasName: this.getNgPropertyAliasName(decorator),
type: {
name: symbolDescription.type,
options: options,
kindName: ts.SyntaxKind[propertyDeclaration.type?.kind]
},
description: tags.description && tags.description.text ? tags.description.text : symbolDescription.comment,
default: '',
tags: tags
};

if (propertyKind === 'Input') {
property.default =
(tags.default && tags.default.text) || getPropertyValue(propertyDeclaration, symbolDescription.type);
}
properties.push(property);
}
properties.push(property);
}
}
});
Expand Down
12 changes: 10 additions & 2 deletions packages/ngdoc/src/parser/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,14 @@ export function findNodes<T extends ts.Node>(
// return result;
// }

interface DocTagResult {
export interface DocTagResult {
description?: ts.JSDocTagInfo;
default?: ts.JSDocTagInfo;
deprecated?: ts.JSDocTagInfo;
name?: ts.JSDocTagInfo;
[key: string]: ts.JSDocTagInfo;
}
interface MethodDocTagResult {
export interface MethodDocTagResult {
description?: ts.JSDocTagInfo;
default?: ts.JSDocTagInfo;
deprecated?: ts.JSDocTagInfo;
Expand All @@ -194,6 +195,13 @@ export function getDocTagsBySymbol(symbol: ts.Symbol): DocTagResult {
}, {});
}

/**
* 公开的类或者属性,非 private 和 internal 标记
*/
export function isPublicTag(tags: DocTagResult) {
return !(tags.private || tags.internal);
}

export function getDocTagsBySignature(symbol: ts.Signature): MethodDocTagResult {
const tags = symbol.getJsDocTags();
return tags.reduce((result, item) => {
Expand Down
1 change: 1 addition & 0 deletions packages/ngdoc/src/types/directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface NgDirectiveDoc extends NgDirectiveMetadata {
type: NgDocItemType;
name?: string;
description?: string;
className?: string;
properties?: NgPropertyDoc[];
}

Expand Down
26 changes: 14 additions & 12 deletions packages/ngdoc/test/fixtures/full/input/button.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Component, Directive, OnInit, Input, Output, EventEmitter, ContentChild, TemplateRef } from '@angular/core';
import { Component, Directive, OnInit, Input, Output, EventEmitter, ContentChild, TemplateRef, ViewChild } from '@angular/core';

export type ButtonSize = 'lg' | 'md' | 'sm';

/**
* General Button Component description.
* @export
* @name thy-button
* @class ButtonComponent
* @implements {OnInit}
*/
Expand All @@ -15,7 +15,6 @@ export type ButtonSize = 'lg' | 'md' | 'sm';
exportAs: 'thyButton'
})
export class ButtonComponent implements OnInit {

private type = '';
private loading = false;

Expand All @@ -25,14 +24,14 @@ export class ButtonComponent implements OnInit {
*/
@Input('thyTypeAlias') thyType: 'primary' | 'info' | 'success' = 'primary';

/**
/**
* Button Size
* @deprecated
* @default md
*/
@Input() thySize: ButtonSize;

@Input() set thyLoading(loading: boolean){
@Input() set thyLoading(loading: boolean) {
this.loading = loading;
}

Expand All @@ -44,22 +43,25 @@ export class ButtonComponent implements OnInit {
/**
* Template
*/
@ContentChild('template') templateRef: TemplateRef<any>;

constructor() { }
@ContentChild('template') templateRef: TemplateRef<unknown>;

ngOnInit(): void { }
}
/**
* @private
*/
@ContentChild('view') viewChild: TemplateRef<unknown>;

constructor() {}

ngOnInit(): void {}
}

/**
* General Button Icon Directive description.
* @export
* @class ButtonIconComponent
* @implements {OnInit}
*/
@Directive({
selector: '[thyButtonIcon]',
@Directive({
selector: '[thyButtonIcon]'
})
export class ButtonIconComponent implements OnInit {}
7 changes: 5 additions & 2 deletions packages/ngdoc/test/fixtures/full/output.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[
{
"type": "component",
"name": "ButtonComponent",
"name": "thy-button",
"className": "ButtonComponent",
"description": "General Button Component description.",
"selector": "thy-button",
"templateUrl": "./button.component.html",
Expand Down Expand Up @@ -88,7 +89,7 @@
"name": "templateRef",
"aliasName": "template",
"type": {
"name": "TemplateRef<any>",
"name": "TemplateRef<unknown>",
"options": null,
"kindName": "TypeReference"
},
Expand All @@ -101,6 +102,7 @@
{
"type": "directive",
"name": "ButtonIconComponent",
"className": "ButtonIconComponent",
"description": "General Button Icon Directive description.",
"selector": "[thyButtonIcon]",
"templateUrl": null,
Expand All @@ -113,6 +115,7 @@
{
"type": "component",
"name": "LoadingComponent",
"className": "LoadingComponent",
"description": "General Loading Component description.",
"selector": "thy-loading",
"templateUrl": "./loading.component.html",
Expand Down
1 change: 1 addition & 0 deletions packages/toolkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"url": "https://github.com/docgeni/docgeni/issues"
},
"dependencies": {
"@angular-devkit/core": "^12.2.18",
"camelcase": "^6.0.0",
"chalk": "^3.0.0",
"change-case": "^4.1.1",
Expand Down
27 changes: 27 additions & 0 deletions packages/toolkit/src/fs/docgeni-scoped.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { virtualFs } from '@angular-devkit/core';
import { DocgeniScopedHost } from './docgeni-scoped';
import { normalize } from '../fs';

describe('#docgeni-scoped', () => {
it('should resolve success without root', async () => {
const docgeniScopedHost = new DocgeniScopedHost(
new virtualFs.test.TestHost({
'/d/root/hello/hello.ts': 'hello'
}),
'/d/root'
);
const exists = await docgeniScopedHost.exists(normalize('hello/hello.ts')).toPromise();
expect(exists).toEqual(true);
});

it('should resolve success with root', async () => {
const docgeniScopedHost = new DocgeniScopedHost(
new virtualFs.test.TestHost({
'/d/root/hello/hello.ts': 'hello'
}),
'/d/root'
);
const exists = await docgeniScopedHost.exists(normalize('/d/root/hello/hello.ts')).toPromise();
expect(exists).toEqual(true);
});
});

0 comments on commit 41a15a1

Please sign in to comment.