chore(doclint): support classes inheritance (#935)

This patch:
- gives meaningful names to doclint tests
- supports classes inheritance in documentation linter. When class A
  extends class B, all methods of class B are added to documentation of
  class A.

This is a prerequisite for Object Handles: ElementHandle will be
extending ObjectHandle.

References #382
This commit is contained in:
Andrey Lushnikov
2017-10-02 13:38:44 -07:00
committed by GitHub
parent 8bcf550bb6
commit 6c9a99477b
33 changed files with 127 additions and 11 deletions

View File

@@ -21,6 +21,8 @@ const Documentation = require('./Documentation');
class JSOutline {
constructor(text) {
this.classes = [];
/** @type {!Map<string, string>} */
this.inheritance = new Map();
this.errors = [];
this._eventsByClassName = new Map();
this._currentClassName = null;
@@ -44,6 +46,9 @@ class JSOutline {
_onClassDeclaration(node) {
this._flushClassIfNeeded();
this._currentClassName = this._extractText(node.id);
const superClass = this._extractText(node.superClass);
if (superClass)
this.inheritance.set(this._currentClassName, superClass);
}
_onMethodDefinition(node) {
@@ -140,6 +145,31 @@ class JSOutline {
}
}
/**
* @param {!Array<!Documentation.Class>} classes
* @param {!Map<string, string>} inheritance
* @return {!Array<!Documentation.Class>}
*/
function recreateClassesWithInheritance(classes, inheritance) {
const classesByName = new Map(classes.map(cls => [cls.name, cls]));
return classes.map(cls => {
const membersMap = new Map();
for (let wp = cls; wp; wp = classesByName.get(inheritance.get(wp.name))) {
for (const member of wp.membersArray) {
// Member was overridden.
const memberId = member.type + ':' + member.name;
if (membersMap.has(memberId))
continue;
// Do not inherit constructors
if (wp !== cls && member.name === 'constructor' && member.type === 'method')
continue;
membersMap.set(memberId, member);
}
}
return new Documentation.Class(cls.name, Array.from(membersMap.values()));
});
}
/**
* @param {!Array<!Source>} sources
* @return {!Promise<{documentation: !Documentation, errors: !Array<string>}>}
@@ -147,12 +177,15 @@ class JSOutline {
module.exports = async function(sources) {
const classes = [];
const errors = [];
const inheritance = new Map();
for (const source of sources) {
const outline = new JSOutline(source.text());
classes.push(...outline.classes);
errors.push(...outline.errors);
for (const entry of outline.inheritance)
inheritance.set(entry[0], entry[1]);
}
const documentation = new Documentation(classes);
const documentation = new Documentation(recreateClassesWithInheritance(classes, inheritance));
return { documentation, errors };
};