Review documentation plus some tools fix (#5100)

* review 3.5.0 doc

* fix documentation

* fix documentation

* fix documentation
This commit is contained in:
Eugenio Romano
2019-09-26 10:27:04 +01:00
committed by GitHub
parent bfc7e91eb6
commit 3dc92beeb9
83 changed files with 3717 additions and 41598 deletions

View File

@@ -91,7 +91,7 @@ var MethodSigInfo = /** @class */ (function () {
this.name = sourceData.name;
this.docText = sourceData.summary || '';
this.docText = this.docText.replace(/[\n\r]+/g, ' ').trim();
if (!this.docText) {
if (!this.docText && this.name.indexOf('service') > 0) {
this.errorMessages.push("Warning: method \"" + sourceData.name + "\" has no doc text.");
}
this.returnType = sourceData.syntax['return'].type || '';
@@ -101,7 +101,7 @@ var MethodSigInfo = /** @class */ (function () {
if (this.returnDocText.toLowerCase() === 'nothing') {
this.returnsSomething = false;
}
if (this.returnsSomething && !this.returnDocText) {
if (this.returnsSomething && !this.returnDocText && this.name.indexOf('service') > 0) {
this.errorMessages.push("Warning: Return value of method \"" + sourceData.name + "\" has no doc text.");
}
this.isDeprecated = false;
@@ -116,7 +116,7 @@ var MethodSigInfo = /** @class */ (function () {
var paramStrings = [];
if (sourceData.syntax.parameters) {
sourceData.syntax.parameters.forEach(function (rawParam) {
if (!rawParam.description) {
if (rawParam.name && !rawParam.description && !rawParam.name.startWith('on')) {
_this.errorMessages.push("Warning: parameter \"" + rawParam.name + "\" of method \"" + sourceData.name + "\" has no doc text.");
}
var param = new ParamInfo(rawParam);

View File

@@ -132,7 +132,7 @@ export class MethodSigInfo {
this.docText = sourceData.summary || '';
this.docText = this.docText.replace(/[\n\r]+/g, ' ').trim();
if (!this.docText) {
if (!this.docText && this.name.indexOf('service') > 0) {
this.errorMessages.push(`Warning: method "${sourceData.name}" has no doc text.`);
}
@@ -145,7 +145,7 @@ export class MethodSigInfo {
this.returnsSomething = false;
}
if (this.returnsSomething && !this.returnDocText) {
if (this.returnsSomething && !this.returnDocText && this.name.indexOf('service') > 0) {
this.errorMessages.push(`Warning: Return value of method "${sourceData.name}" has no doc text.`);
}
@@ -165,7 +165,7 @@ export class MethodSigInfo {
if (sourceData.syntax.parameters) {
sourceData.syntax.parameters.forEach(rawParam => {
if (!rawParam.description) {
if (rawParam.name && !rawParam.description && !rawParam.name.startWith('on')) {
this.errorMessages.push(`Warning: parameter "${rawParam.name}" of method "${sourceData.name}" has no doc text.`);
}

View File

@@ -143,10 +143,11 @@ function getMDMethodParams(methItem) {
paramName = paramNameNode.text().item.value.replace(/:/, '');
}
else {
paramName = paramListItem.childNav
.paragraph().childNav
.strong().childNav
.text().item.value;
var item = paramListItem.childNav.paragraph().childNav
.strong().childNav.text();
if (paramName) {
paramName = item.value;
}
}
var paramDoc = paramListItem.childNav
.paragraph().childNav

View File

@@ -87,28 +87,28 @@ function getPropDocsFromMD(tree, sectionHeading, docsColumn) {
const nav = new MDNav(tree);
const classMemHeading = nav
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === 'Class members');
});
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === 'Class members');
});
const propsTable = classMemHeading
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === sectionHeading);
}).table();
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === sectionHeading);
}).table();
let propTableRow = propsTable.childNav
.tableRow(() => true, 1).childNav;
.tableRow(() => true, 1).childNav;
let i = 1;
while (!propTableRow.empty) {
const propName = propTableRow
.tableCell().childNav
.text().item.value;
.tableCell().childNav
.text().item.value;
const propDocText = propTableRow
.tableCell(() => true, docsColumn).childNav
.text().item;
.tableCell(() => true, docsColumn).childNav
.text().item;
if (propDocText) {
result[propName] = propDocText.value;
@@ -116,7 +116,7 @@ function getPropDocsFromMD(tree, sectionHeading, docsColumn) {
i++;
propTableRow = propsTable.childNav
.tableRow(() => true, i).childNav;
.tableRow(() => true, i).childNav;
}
return result;
@@ -128,24 +128,24 @@ function getMethodDocsFromMD(tree) {
const nav = new MDNav(tree);
const classMemHeading = nav
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === 'Class members');
});
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === 'Class members');
});
const methListItems = classMemHeading
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === 'Methods');
}).list().childNav;
.heading(h => {
return (h.children[0].type === 'text') && (h.children[0].value === 'Methods');
}).list().childNav;
let methItem = methListItems
.listItem();
.listItem();
let i = 0;
while (!methItem.empty) {
const methNameSection = methItem.childNav
.paragraph().childNav
.strong().childNav;
.paragraph().childNav
.strong().childNav;
let methName = '';
@@ -154,9 +154,9 @@ function getMethodDocsFromMD(tree) {
methName = methNameSection.text().item.value;
const methDoc = methItem.childNav
.paragraph().childNav
.html()
.text().value;
.paragraph().childNav
.html()
.text().value;
const params = getMDMethodParams(methItem);
@@ -169,7 +169,7 @@ function getMethodDocsFromMD(tree) {
i++;
methItem = methListItems
.listItem(l => true, i);
.listItem(l => true, i);
}
return result;
@@ -181,27 +181,30 @@ function getMDMethodParams(methItem: MDNav) {
const paramList = methItem.childNav.list().childNav;
const paramListItems = paramList
.listItems();
.listItems();
paramListItems.forEach(paramListItem => {
const paramNameNode = paramListItem.childNav
.paragraph().childNav
.emph().childNav;
.paragraph().childNav
.emph().childNav;
let paramName;
if (!paramNameNode.empty) {
paramName = paramNameNode.text().item.value.replace(/:/, '');
} else {
paramName = paramListItem.childNav
.paragraph().childNav
.strong().childNav
.text().item.value;
let item = paramListItem.childNav.paragraph().childNav
.strong().childNav.text();
if (paramName) {
paramName = item.value;
}
}
const paramDoc = paramListItem.childNav
.paragraph().childNav
.text(t => true, 1).value; // item.value;
.paragraph().childNav
.text(t => true, 1).value; // item.value;
result[paramName] = paramDoc.replace(/^[ -]+/, '');
});

View File

@@ -49,7 +49,7 @@ function readPhase(mdCache, aggData) {
function getFileData(tree, pathname, aggData) {
var compName = pathname;
var angNameRegex = /([a-zA-Z0-9\-]+)\.((component)|(directive)|(model)|(pipe)|(service)|(widget))/;
var angNameRegex = /([a-zA-Z0-9\-]+)\.((component)|(directive)|(model)|(pipe)|(service)|(widget)|(dialog))/;
if (!compName.match(angNameRegex))
return;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
{
"export-last-version": "export-new.json",
"export-versions": [
"export-2.0.0.json",
"export-2.1.0.json",
"export-2.2.0.json",
"export-2.3.0.json",
"export-2.5.0.json"
]
}

View File

@@ -1,373 +0,0 @@
import * as ts from "typescript";
import * as fs from "fs";
import chalk from "chalk";
var nconf = require('nconf');
var basePath = "./tools/export-check/";
nconf.add('config', { type: 'file', file: `${basePath}export-check-config.json` });
var newLibExports = basePath + nconf.get('export-last-version');
var exportFilesVersions = nconf.get('export-versions').map((currentFile) => {
return basePath + currentFile;
});
interface DocEntry {
position?: {
line: number,
character: number,
fileName: string
},
name?: string,
skipError?: boolean
};
let error_array = [];
let warning_array = [];
let exportedAllPath: Array<string> = [];
let classList: Array<any> = [];
let add_error = function (error: string, nameClass: string) {
let findErrorClass = false;
error_array.forEach((currentError) => {
if (currentError.nameClass === nameClass) {
findErrorClass = true;
return;
}
});
if (!findErrorClass) {
error_array.push({
error: error,
nameClass: nameClass
});
}
}
let count_error = 0;
let count_warning = 0;
let print_errors = function () {
error_array.forEach((current_error) => {
console.log(chalk.red(`[${++count_error}] ${current_error.error}\n`));
});
}
let add_warning = function (warning: string, nameClass: string, arrayCall: string[]) {
let findWarningClass = false;
warning_array.forEach((currentWarning) => {
if (currentWarning.nameClass === nameClass) {
findWarningClass = true;
return;
}
});
if (!findWarningClass) {
warning_array.push({
warning: warning,
nameClass: nameClass,
arrayCall: arrayCall
});
}
}
let print_warnings = function () {
warning_array.forEach((current_warning) => {
console.log(chalk.yellow(`[${++count_warning}] ${current_warning.warning} \n ${current_warning.arrayCall} \n`));
});
}
let currentErrorPostion = function (exportEntry) {
return ` ${exportEntry.position.fileName} (${exportEntry.position.line},${exportEntry.position.character})`
}
let check_export = function (exportLastMajor: any, exportNew: any) {
exportLastMajor.forEach((currentexportLastMajor) => {
let currentexportNew = exportNew.filter((currentexportNew) => {
return currentexportNew.name === currentexportLastMajor.name;
});
if (currentexportNew.length > 1) {
let arrayCall = [];
currentexportNew.forEach((error) => {
arrayCall.push(`${currentErrorPostion(error)}`);
})
add_warning(`Multiple export ${currentexportNew[0].name} times ${currentexportNew.length}`, currentexportNew[0].name, arrayCall);
} else if (currentexportNew.length === 0) {
if (!currentexportLastMajor.skipError) {
add_error(`Not find export ${currentexportLastMajor.name} , old path: [${currentErrorPostion(currentexportLastMajor)}]`, currentexportLastMajor.name);
}
}
});
};
let expandStarExport = function (node: ts.Node): ts.ExportDeclaration {
const ed = node as ts.Node as ts.ExportDeclaration;
const exports = [{ name: "x" }];
const exportSpecifiers = exports.map(e => ts.createExportSpecifier(e.name, e.name));
const exportClause = ts.createNamedExports(exportSpecifiers);
const newEd = ts.updateExportDeclaration(ed, ed.decorators, ed.modifiers, exportClause, ed.moduleSpecifier);
return newEd as ts.ExportDeclaration
};
/** Generate documentation for all classes in a set of .ts files */
function generatExportList(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 exportCurrentVersion: DocEntry[] = [];
// Visit every sourceFile in the program
for (const sourceFile of program.getSourceFiles()) {
if (!sourceFile.isDeclarationFile) {
// Walk the tree to search for classes
ts.forEachChild(sourceFile, visit);
}
}
classList.forEach((classNode) => {
if (classNode.symbol.parent) {
let pathClass = classNode.symbol.parent.escapedName.replace(/"/g, "");
exportedAllPath.forEach((currenPath) => {
let pathNoExtension = currenPath.replace(/\.[^/.]+$/, "");
if (pathNoExtension === pathClass) {
// console.log('pathClass'+ pathClass);
// console.log('pathNoExtension '+ pathNoExtension);
extractExport(classNode);
return;
}
});
}
});
exportCurrentVersion.sort((nameA, nameB) => nameA.name.localeCompare(nameB.name));
console.log(chalk.green(`Saving new export in ${newLibExports}`));
fs.writeFileSync(newLibExports, JSON.stringify(exportCurrentVersion, undefined, 4));
var exportNewJSON = JSON.parse(JSON.stringify(exportCurrentVersion));
exportFilesVersions.forEach((currentExportVersionFile) => {
error_array = [];
warning_array = [];
try {
var currentExportVersionJSON = JSON.parse(fs.readFileSync(`${currentExportVersionFile}`, 'utf8'));
} catch (error) {
console.log(chalk.red(`${currentExportVersionFile} json not present`));
throw new Error(`Undetected export comapring file ${currentExportVersionFile}`);
}
console.log(chalk.green(`Comparing ${newLibExports} and ${currentExportVersionFile}`));
check_export(currentExportVersionJSON, exportNewJSON);
print_warnings();
print_errors();
if (error_array.length > 0) {
throw new Error('Export problems detected');
} else {
return;
}
})
function extractExport(node: ts.Node) {
//skip file with export-check: exclude comment
if (node.getFullText(node.getSourceFile()).indexOf('export-check: exclude') > 0) {
return;
}
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
//console.log(line + " " + character + " " + node.getSourceFile().fileName);
let symbol = checker.getSymbolAtLocation(node);
if (symbol) {
let arryCalls = recursiveStackSave(node);
let className: any = symbol.escapedName;
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
exportCurrentVersion.push(serializeClass(className, line, character, filename, arryCalls));
// if (className === "ContentMetadataService") {
// console.log(chalk.red("exportedAllPath" + exportedAllPath));
// console.log(chalk.red("ContentMetadataService"));
// recursiveStack(node);
// }
} else {
let arryCalls = recursiveStackSave(node);
let className: any = (node as ts.ClassDeclaration).name.escapedText;
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
exportCurrentVersion.push(serializeClass(className, line, character, filename, arryCalls));
// if (className === "ContentMetadataService") {
// console.log(chalk.greenBright("exportedAllPath" + exportedAllPath));
// console.log(chalk.greenBright("ContentMetadataService"));
// recursiveStack(node);
// }
}
}
function recursiveStackSave(node: ts.Node, arrayCalls?: string[]) {
if (!arrayCalls) {
arrayCalls = [];
}
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
arrayCalls.push(node.getSourceFile().fileName);
if (node.parent) {
recursiveStackSave(node.parent, arrayCalls)
}
return arrayCalls;
}
function recursiveStack(node: ts.Node) {
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
console.log(chalk.bgCyan(line + " " + character + " " + node.getSourceFile().fileName));
if (node.parent) {
recursiveStack(node.parent)
}
}
/** visit nodes finding exported classes */
function visit(node: ts.Node) {
// Only consider exported nodes
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
if (node.decorators) {
node.decorators.forEach((decorator) => {
visit(decorator as ts.Node);
});
}
classList.push(node);
}
if (node.kind === ts.SyntaxKind.PropertyAssignment) {
const initializer = (node as ts.PropertyAssignment).initializer;
visit(initializer as ts.Node);
}
if (node.kind === ts.SyntaxKind.Identifier) {
extractExport(node);
}
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
(node as ts.ArrayLiteralExpression).elements.forEach((element) => {
visit(element as ts.Node);
});
}
if (node.kind === ts.SyntaxKind.Decorator &&
((node as ts.Decorator).expression as any).expression.text === "NgModule") {
((node as ts.Decorator).expression as any).arguments.forEach((argument) => {
argument.properties.forEach((property) => {
if (property.name.escapedText === "exports") {
visit(property as ts.Node);
}
});
});
}
if (ts.isExportDeclaration(node)) {
if (node.exportClause) {
node.exportClause.elements.forEach(exportCurrent => {
extractExport(exportCurrent as ts.Node);
});
} else {
(node.parent as any).resolvedModules.forEach((currentModule) => {
if (currentModule) {
let find;
exportedAllPath.forEach((currentExported) => {
if (currentModule.resolvedFileName === currentExported) {
find = currentExported;
}
})
if (!find) {
exportedAllPath.push(currentModule.resolvedFileName);
}
}
})
visit(node.moduleSpecifier);
}
}
if (ts.isModuleDeclaration(node)) {
// This is a namespace, visit its children
ts.forEachChild(node, visit);
}
}
/** Serialize a symbol into a json object */
function serializeSymbol(className: string, line?: number, character?: number, fileName?: string, arryCalls?: string[]): DocEntry {
return {
position: {
line: line,
character: character,
fileName: fileName
},
name: className
};
}
/** Serialize a class symbol information */
function serializeClass(className: string, line?: number, character?: number, fileName?: string, arryCalls?: string[]) {
let details = serializeSymbol(className, line, character, fileName, arryCalls);
return details;
}
/** True if this is visible outside this file, false otherwise */
function isNodeExported(node: ts.Node): boolean {
return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 || (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile);
}
}
generatExportList(process.argv.slice(2), {
target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS, removeComments: false
});