-
Notifications
You must be signed in to change notification settings - Fork 6.8k
/
Copy pathasync-functions.ts
69 lines (58 loc) · 2.48 KB
/
async-functions.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import {DocCollection, Processor} from 'dgeni';
import {ApiDoc} from 'dgeni-packages/typescript/api-doc-types/ApiDoc';
import {FunctionExportDoc} from 'dgeni-packages/typescript/api-doc-types/FunctionExportDoc';
import {MethodMemberDoc} from 'dgeni-packages/typescript/api-doc-types/MethodMemberDoc';
import ts from 'typescript';
/** Type describing a function-like API doc (i.e. a function, or a class method member). */
type FunctionLikeDoc = (FunctionExportDoc | MethodMemberDoc) & {
returns?: {description: string};
isAsync?: boolean;
};
/**
* Processor that marks documents for functions which are asynchronous. Additionally, the
* processor automatically sets the @return description for asynchronous methods which do
* not return any value.
*/
export class AsyncFunctionsProcessor implements Processor {
name = 'async-functions';
$runBefore = ['categorizer'];
$process(docs: DocCollection) {
docs.forEach((doc: ApiDoc) => {
if (!isFunctionLikeDoc(doc)) {
return;
}
const typeString = getTypeOfFunctionLikeDoc(doc);
// Mark asynchronous function API documents. Async functions can be detected
// in multiple ways. Most commonly by checking the type symbol name and ensuring
// there is a type argument, or by just checking the stringified type. For simplicity,
// we just check the stringified type.
if (typeString && typeString.startsWith('Promise<')) {
doc.isAsync = true;
}
// Add a JSDoc @returns description for void asynchronous functions.
if (!doc.returns && typeString === 'Promise<void>') {
doc.returns = {description: 'Promise that resolves when the action completes.'};
}
});
}
}
/**
* Gets the type of the function-like doc. If no explicit type has been specified,
* the type checker is used to compute a type string based on the function body.
*/
function getTypeOfFunctionLikeDoc(doc: FunctionLikeDoc): string | null {
if (doc.type) {
return doc.type;
}
const decl = doc.declaration as ts.MethodDeclaration | ts.FunctionDeclaration;
const signature = doc.typeChecker.getSignatureFromDeclaration(decl);
if (!signature) {
return null;
}
const returnType = doc.typeChecker.getReturnTypeOfSignature(signature);
return doc.typeChecker.typeToString(returnType);
}
/** Whether the given API doc is a function-like doc. */
function isFunctionLikeDoc(doc: ApiDoc): doc is FunctionLikeDoc {
return doc instanceof FunctionExportDoc || doc instanceof MethodMemberDoc;
}