Add a new API sample
Родитель
5c9ca9d8cf
Коммит
8bc7c8eadc
|
@ -433,4 +433,154 @@ function compile(sourceFiles: string[], moduleSearchLocations: string[]): void {
|
|||
|
||||
/// do something with program...
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### Using the TypeChecker
|
||||
|
||||
In this sample we will walk the AST and use the checker to serialize class information.
|
||||
We use the typeCheker to get symbol and type information, including JSDoc comments for the class, constructor and constructor parameters.
|
||||
|
||||
```ts
|
||||
/// <reference path="typings/node/node.d.ts" />
|
||||
|
||||
import * as ts from "typescript";
|
||||
import * as fs from "fs";
|
||||
|
||||
interface DocEntry {
|
||||
name?: string,
|
||||
fileName?: string,
|
||||
documentation?: string,
|
||||
type?: string,
|
||||
constructors?: DocEntry[],
|
||||
parameters?: DocEntry[],
|
||||
returnType?:string
|
||||
};
|
||||
|
||||
/** Generate documention for all classes in a set of .ts files */
|
||||
function generateDocumentation(fileNames: string[], options: ts.CompilerOptions): void {
|
||||
// Build a program using the set of root file names in fileNames
|
||||
let program = ts.createProgram(fileNames, options);
|
||||
|
||||
// Get the checker, we will use it to find more about classes
|
||||
let checker = program.getTypeChecker();
|
||||
|
||||
let output: DocEntry[] = [];
|
||||
|
||||
// Visit every sourceFile in the program
|
||||
program.getSourceFiles().forEach(sourceFile => {
|
||||
// Walk the tree to search for classes
|
||||
ts.forEachChild(sourceFile, visit);
|
||||
});
|
||||
|
||||
// print out the doc
|
||||
fs.writeFileSync("classes.json", JSON.stringify(output, undefined, 4));
|
||||
|
||||
/** Serialize a symbol into a json object */
|
||||
function serializeSymbol(symbol: ts.Symbol): DocEntry {
|
||||
return {
|
||||
name: symbol.getName(),
|
||||
documentation: ts.displayPartsToString(symbol.getDocumentationComment()),
|
||||
type: checker.typeToString(checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration))
|
||||
};
|
||||
}
|
||||
|
||||
/** Serialize a class symbol infomration */
|
||||
function serializeClass(symbol: ts.Symbol) {
|
||||
let details = serializeSymbol(symbol);
|
||||
|
||||
// Get the construct signatures
|
||||
let constructorType = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);
|
||||
details.constructors = constructorType.getConstructSignatures().map(serializeSignature);
|
||||
return details;
|
||||
}
|
||||
|
||||
/** Serialize a signature (call or construct) */
|
||||
function serializeSignature(signature: ts.Signature) {
|
||||
return {
|
||||
paramters: signature.parameters.map(serializeSymbol),
|
||||
returnType: checker.typeToString(signature.getReturnType()),
|
||||
documentation: ts.displayPartsToString(signature.getDocumentationComment())
|
||||
};
|
||||
}
|
||||
|
||||
/** True if this is visible outside this file, false otherwise */
|
||||
function isNodeExported(node: ts.Node): boolean {
|
||||
return (node.flags & ts.NodeFlags.Export) !== 0 || (node.parent && node.parent.kind === ts.SyntaxKind.SourceFile);
|
||||
}
|
||||
|
||||
/** vist nodes finding exported classes */
|
||||
function visit(node: ts.Node) {
|
||||
// Only consider exported nodes
|
||||
if (!isNodeExported(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
|
||||
// This is a class, get its symbol
|
||||
let symbol = checker.getSymbolAtLocation((<ts.ClassDeclaration>node).name);
|
||||
output.push(serializeClass(symbol));
|
||||
}
|
||||
else if (node.kind === ts.SyntaxKind.ModuleDeclaration) {
|
||||
// This is a namespace, visit its children
|
||||
ts.forEachChild(node, visit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateDocumentation(process.argv.slice(2), {
|
||||
target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS
|
||||
});
|
||||
```
|
||||
|
||||
to try this:
|
||||
|
||||
```shell
|
||||
tsc docGenerator.ts --m commonjs
|
||||
node docGenerator.js test.ts
|
||||
```
|
||||
|
||||
Passing an input like:
|
||||
|
||||
```ts
|
||||
/**
|
||||
* Documentation for C
|
||||
*/
|
||||
class C {
|
||||
/**
|
||||
* constructor documentation
|
||||
* @param a my paramter documentation
|
||||
* @param b another parameter documentation
|
||||
*/
|
||||
constructor(a: string, b: C) { }
|
||||
}
|
||||
```
|
||||
|
||||
We should get output like:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "C",
|
||||
"documentation": "Documentation for C ",
|
||||
"type": "typeof C",
|
||||
"constructors": [
|
||||
{
|
||||
"paramters": [
|
||||
{
|
||||
"name": "a",
|
||||
"documentation": "my paramter documentation",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"documentation": "another parameter documentation",
|
||||
"type": "C"
|
||||
}
|
||||
],
|
||||
"returnType": "C",
|
||||
"documentation": "constructor documentation"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
|
Загрузка…
Ссылка в новой задаче