From 6c9a99477bf5045fbfe23c236a599aec2429108a Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Mon, 2 Oct 2017 13:38:44 -0700 Subject: [PATCH] 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 --- utils/doclint/check_public_api/JSBuilder.js | 35 ++++++++++- .../doc.md | 0 .../foo.js | 0 .../result.txt | 0 .../test/{08-return => check-returns}/doc.md | 0 .../test/{08-return => check-returns}/foo.js | 0 .../{08-return => check-returns}/result.txt | 0 .../test/{07-sorting => check-sorting}/doc.md | 0 .../test/{07-sorting => check-sorting}/foo.js | 0 .../{07-sorting => check-sorting}/result.txt | 0 .../doc.md | 0 .../foo.js | 0 .../result.txt | 0 .../{01-class-errors => diff-classes}/doc.md | 0 .../{01-class-errors => diff-classes}/foo.js | 0 .../other.js | 0 .../result.txt | 0 .../{05-event-errors => diff-events}/doc.md | 0 .../{05-event-errors => diff-events}/foo.js | 0 .../result.txt | 0 .../{02-method-errors => diff-methods}/doc.md | 0 .../{02-method-errors => diff-methods}/foo.js | 0 .../result.txt | 0 .../doc.md | 0 .../foo.js | 0 .../result.txt | 0 .../foo.js | 0 .../result.txt | 0 .../test/js-builder-inheritance/foo.js | 20 ++++++ .../test/js-builder-inheritance/result.txt | 62 +++++++++++++++++++ .../doc.md | 0 .../result.txt | 0 utils/doclint/check_public_api/test/test.js | 21 ++++--- 33 files changed, 127 insertions(+), 11 deletions(-) rename utils/doclint/check_public_api/test/{06-duplicates => check-duplicates}/doc.md (100%) rename utils/doclint/check_public_api/test/{06-duplicates => check-duplicates}/foo.js (100%) rename utils/doclint/check_public_api/test/{06-duplicates => check-duplicates}/result.txt (100%) rename utils/doclint/check_public_api/test/{08-return => check-returns}/doc.md (100%) rename utils/doclint/check_public_api/test/{08-return => check-returns}/foo.js (100%) rename utils/doclint/check_public_api/test/{08-return => check-returns}/result.txt (100%) rename utils/doclint/check_public_api/test/{07-sorting => check-sorting}/doc.md (100%) rename utils/doclint/check_public_api/test/{07-sorting => check-sorting}/foo.js (100%) rename utils/doclint/check_public_api/test/{07-sorting => check-sorting}/result.txt (100%) rename utils/doclint/check_public_api/test/{04-bad-arguments => diff-arguments}/doc.md (100%) rename utils/doclint/check_public_api/test/{04-bad-arguments => diff-arguments}/foo.js (100%) rename utils/doclint/check_public_api/test/{04-bad-arguments => diff-arguments}/result.txt (100%) rename utils/doclint/check_public_api/test/{01-class-errors => diff-classes}/doc.md (100%) rename utils/doclint/check_public_api/test/{01-class-errors => diff-classes}/foo.js (100%) rename utils/doclint/check_public_api/test/{01-class-errors => diff-classes}/other.js (100%) rename utils/doclint/check_public_api/test/{01-class-errors => diff-classes}/result.txt (100%) rename utils/doclint/check_public_api/test/{05-event-errors => diff-events}/doc.md (100%) rename utils/doclint/check_public_api/test/{05-event-errors => diff-events}/foo.js (100%) rename utils/doclint/check_public_api/test/{05-event-errors => diff-events}/result.txt (100%) rename utils/doclint/check_public_api/test/{02-method-errors => diff-methods}/doc.md (100%) rename utils/doclint/check_public_api/test/{02-method-errors => diff-methods}/foo.js (100%) rename utils/doclint/check_public_api/test/{02-method-errors => diff-methods}/result.txt (100%) rename utils/doclint/check_public_api/test/{03-property-errors => diff-properties}/doc.md (100%) rename utils/doclint/check_public_api/test/{03-property-errors => diff-properties}/foo.js (100%) rename utils/doclint/check_public_api/test/{03-property-errors => diff-properties}/result.txt (100%) rename utils/doclint/check_public_api/test/{09-js-builder => js-builder-common}/foo.js (100%) rename utils/doclint/check_public_api/test/{09-js-builder => js-builder-common}/result.txt (100%) create mode 100644 utils/doclint/check_public_api/test/js-builder-inheritance/foo.js create mode 100644 utils/doclint/check_public_api/test/js-builder-inheritance/result.txt rename utils/doclint/check_public_api/test/{10-md-builder => md-builder-common}/doc.md (100%) rename utils/doclint/check_public_api/test/{10-md-builder => md-builder-common}/result.txt (100%) diff --git a/utils/doclint/check_public_api/JSBuilder.js b/utils/doclint/check_public_api/JSBuilder.js index 843bdb94..26c77a79 100644 --- a/utils/doclint/check_public_api/JSBuilder.js +++ b/utils/doclint/check_public_api/JSBuilder.js @@ -21,6 +21,8 @@ const Documentation = require('./Documentation'); class JSOutline { constructor(text) { this.classes = []; + /** @type {!Map} */ + 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} classes + * @param {!Map} inheritance + * @return {!Array} + */ +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} sources * @return {!Promise<{documentation: !Documentation, errors: !Array}>} @@ -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 }; }; diff --git a/utils/doclint/check_public_api/test/06-duplicates/doc.md b/utils/doclint/check_public_api/test/check-duplicates/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/06-duplicates/doc.md rename to utils/doclint/check_public_api/test/check-duplicates/doc.md diff --git a/utils/doclint/check_public_api/test/06-duplicates/foo.js b/utils/doclint/check_public_api/test/check-duplicates/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/06-duplicates/foo.js rename to utils/doclint/check_public_api/test/check-duplicates/foo.js diff --git a/utils/doclint/check_public_api/test/06-duplicates/result.txt b/utils/doclint/check_public_api/test/check-duplicates/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/06-duplicates/result.txt rename to utils/doclint/check_public_api/test/check-duplicates/result.txt diff --git a/utils/doclint/check_public_api/test/08-return/doc.md b/utils/doclint/check_public_api/test/check-returns/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/08-return/doc.md rename to utils/doclint/check_public_api/test/check-returns/doc.md diff --git a/utils/doclint/check_public_api/test/08-return/foo.js b/utils/doclint/check_public_api/test/check-returns/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/08-return/foo.js rename to utils/doclint/check_public_api/test/check-returns/foo.js diff --git a/utils/doclint/check_public_api/test/08-return/result.txt b/utils/doclint/check_public_api/test/check-returns/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/08-return/result.txt rename to utils/doclint/check_public_api/test/check-returns/result.txt diff --git a/utils/doclint/check_public_api/test/07-sorting/doc.md b/utils/doclint/check_public_api/test/check-sorting/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/07-sorting/doc.md rename to utils/doclint/check_public_api/test/check-sorting/doc.md diff --git a/utils/doclint/check_public_api/test/07-sorting/foo.js b/utils/doclint/check_public_api/test/check-sorting/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/07-sorting/foo.js rename to utils/doclint/check_public_api/test/check-sorting/foo.js diff --git a/utils/doclint/check_public_api/test/07-sorting/result.txt b/utils/doclint/check_public_api/test/check-sorting/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/07-sorting/result.txt rename to utils/doclint/check_public_api/test/check-sorting/result.txt diff --git a/utils/doclint/check_public_api/test/04-bad-arguments/doc.md b/utils/doclint/check_public_api/test/diff-arguments/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/04-bad-arguments/doc.md rename to utils/doclint/check_public_api/test/diff-arguments/doc.md diff --git a/utils/doclint/check_public_api/test/04-bad-arguments/foo.js b/utils/doclint/check_public_api/test/diff-arguments/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/04-bad-arguments/foo.js rename to utils/doclint/check_public_api/test/diff-arguments/foo.js diff --git a/utils/doclint/check_public_api/test/04-bad-arguments/result.txt b/utils/doclint/check_public_api/test/diff-arguments/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/04-bad-arguments/result.txt rename to utils/doclint/check_public_api/test/diff-arguments/result.txt diff --git a/utils/doclint/check_public_api/test/01-class-errors/doc.md b/utils/doclint/check_public_api/test/diff-classes/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/01-class-errors/doc.md rename to utils/doclint/check_public_api/test/diff-classes/doc.md diff --git a/utils/doclint/check_public_api/test/01-class-errors/foo.js b/utils/doclint/check_public_api/test/diff-classes/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/01-class-errors/foo.js rename to utils/doclint/check_public_api/test/diff-classes/foo.js diff --git a/utils/doclint/check_public_api/test/01-class-errors/other.js b/utils/doclint/check_public_api/test/diff-classes/other.js similarity index 100% rename from utils/doclint/check_public_api/test/01-class-errors/other.js rename to utils/doclint/check_public_api/test/diff-classes/other.js diff --git a/utils/doclint/check_public_api/test/01-class-errors/result.txt b/utils/doclint/check_public_api/test/diff-classes/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/01-class-errors/result.txt rename to utils/doclint/check_public_api/test/diff-classes/result.txt diff --git a/utils/doclint/check_public_api/test/05-event-errors/doc.md b/utils/doclint/check_public_api/test/diff-events/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/05-event-errors/doc.md rename to utils/doclint/check_public_api/test/diff-events/doc.md diff --git a/utils/doclint/check_public_api/test/05-event-errors/foo.js b/utils/doclint/check_public_api/test/diff-events/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/05-event-errors/foo.js rename to utils/doclint/check_public_api/test/diff-events/foo.js diff --git a/utils/doclint/check_public_api/test/05-event-errors/result.txt b/utils/doclint/check_public_api/test/diff-events/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/05-event-errors/result.txt rename to utils/doclint/check_public_api/test/diff-events/result.txt diff --git a/utils/doclint/check_public_api/test/02-method-errors/doc.md b/utils/doclint/check_public_api/test/diff-methods/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/02-method-errors/doc.md rename to utils/doclint/check_public_api/test/diff-methods/doc.md diff --git a/utils/doclint/check_public_api/test/02-method-errors/foo.js b/utils/doclint/check_public_api/test/diff-methods/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/02-method-errors/foo.js rename to utils/doclint/check_public_api/test/diff-methods/foo.js diff --git a/utils/doclint/check_public_api/test/02-method-errors/result.txt b/utils/doclint/check_public_api/test/diff-methods/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/02-method-errors/result.txt rename to utils/doclint/check_public_api/test/diff-methods/result.txt diff --git a/utils/doclint/check_public_api/test/03-property-errors/doc.md b/utils/doclint/check_public_api/test/diff-properties/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/03-property-errors/doc.md rename to utils/doclint/check_public_api/test/diff-properties/doc.md diff --git a/utils/doclint/check_public_api/test/03-property-errors/foo.js b/utils/doclint/check_public_api/test/diff-properties/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/03-property-errors/foo.js rename to utils/doclint/check_public_api/test/diff-properties/foo.js diff --git a/utils/doclint/check_public_api/test/03-property-errors/result.txt b/utils/doclint/check_public_api/test/diff-properties/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/03-property-errors/result.txt rename to utils/doclint/check_public_api/test/diff-properties/result.txt diff --git a/utils/doclint/check_public_api/test/09-js-builder/foo.js b/utils/doclint/check_public_api/test/js-builder-common/foo.js similarity index 100% rename from utils/doclint/check_public_api/test/09-js-builder/foo.js rename to utils/doclint/check_public_api/test/js-builder-common/foo.js diff --git a/utils/doclint/check_public_api/test/09-js-builder/result.txt b/utils/doclint/check_public_api/test/js-builder-common/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/09-js-builder/result.txt rename to utils/doclint/check_public_api/test/js-builder-common/result.txt diff --git a/utils/doclint/check_public_api/test/js-builder-inheritance/foo.js b/utils/doclint/check_public_api/test/js-builder-inheritance/foo.js new file mode 100644 index 00000000..6803c179 --- /dev/null +++ b/utils/doclint/check_public_api/test/js-builder-inheritance/foo.js @@ -0,0 +1,20 @@ +class A { + constructor() { + } + + foo(a) { + } + + bar() { + } +} + +class B extends A { + bar(override) { + } +} + +B.Events = { + // Event with the same name as a super class method. + foo: 'foo' +}; diff --git a/utils/doclint/check_public_api/test/js-builder-inheritance/result.txt b/utils/doclint/check_public_api/test/js-builder-inheritance/result.txt new file mode 100644 index 00000000..1abadad9 --- /dev/null +++ b/utils/doclint/check_public_api/test/js-builder-inheritance/result.txt @@ -0,0 +1,62 @@ +{ + "classes": [ + { + "name": "A", + "members": [ + { + "name": "constructor", + "type": "method", + "hasReturn": false, + "async": false, + "args": [] + }, + { + "name": "foo", + "type": "method", + "hasReturn": false, + "async": false, + "args": [ + "a" + ] + }, + { + "name": "bar", + "type": "method", + "hasReturn": false, + "async": false, + "args": [] + } + ] + }, + { + "name": "B", + "members": [ + { + "name": "bar", + "type": "method", + "hasReturn": false, + "async": false, + "args": [ + "override" + ] + }, + { + "name": "foo", + "type": "event", + "hasReturn": false, + "async": false, + "args": [] + }, + { + "name": "foo", + "type": "method", + "hasReturn": false, + "async": false, + "args": [ + "a" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/utils/doclint/check_public_api/test/10-md-builder/doc.md b/utils/doclint/check_public_api/test/md-builder-common/doc.md similarity index 100% rename from utils/doclint/check_public_api/test/10-md-builder/doc.md rename to utils/doclint/check_public_api/test/md-builder-common/doc.md diff --git a/utils/doclint/check_public_api/test/10-md-builder/result.txt b/utils/doclint/check_public_api/test/md-builder-common/result.txt similarity index 100% rename from utils/doclint/check_public_api/test/10-md-builder/result.txt rename to utils/doclint/check_public_api/test/md-builder-common/result.txt diff --git a/utils/doclint/check_public_api/test/test.js b/utils/doclint/check_public_api/test/test.js index 7c0ed076..348e482f 100644 --- a/utils/doclint/check_public_api/test/test.js +++ b/utils/doclint/check_public_api/test/test.js @@ -47,16 +47,17 @@ afterAll(SX(async function() { })); describe('checkPublicAPI', function() { - it('01-class-errors', SX(testLint)); - it('02-method-errors', SX(testLint)); - it('03-property-errors', SX(testLint)); - it('04-bad-arguments', SX(testLint)); - it('05-event-errors', SX(testLint)); - it('06-duplicates', SX(testLint)); - it('07-sorting', SX(testLint)); - it('08-return', SX(testLint)); - it('09-js-builder', SX(testJSBuilder)); - it('10-md-builder', SX(testMDBuilder)); + it('diff-classes', SX(testLint)); + it('diff-methods', SX(testLint)); + it('diff-properties', SX(testLint)); + it('diff-arguments', SX(testLint)); + it('diff-events', SX(testLint)); + it('check-duplicates', SX(testLint)); + it('check-sorting', SX(testLint)); + it('check-returns', SX(testLint)); + it('js-builder-common', SX(testJSBuilder)); + it('js-builder-inheritance', SX(testJSBuilder)); + it('md-builder-common', SX(testMDBuilder)); }); async function testLint() {