Skip to content

Commit

Permalink
refactor(nest): Better nesting implementation (#732)
Browse files Browse the repository at this point in the history
* refactor(nest): Better nesting implementation

This nesting implementation uses a proper recursive tree algorithm

Fixes #554

BREAKING CHANGE: referencing inferred destructure params without
renaming them, like $0.x, from JSDoc comments will no longer
work. To reference them, instead add a param tag to name the
destructuring param, and then refer to members of that name.

Before:

```js
/**
 * @param {number} $0.x a member of x
 */
function a({ x }) {}
```

After:

```js
/**
 * @param {Object} options
 * @param {number} options.x a member of x
 */
function a({ x }) {}
```

* Address review comments

* Reduce testing node requirement back down to 4

* Don't output empty properties, reduce diff noise

* Rearrange and document params

* Simplify param inference, update test fixtures. This is focused around Array destructuring: documenting destructured array elements with indices instead of names, because the names are purely internal details

* Use temporary fork to get through blocker
  • Loading branch information
tmcw authored Apr 21, 2017
1 parent 9eca36c commit 7374730
Show file tree
Hide file tree
Showing 22 changed files with 1,240 additions and 568 deletions.
75 changes: 45 additions & 30 deletions declarations/comment.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare type DocumentationConfig = {
type DocumentationConfig = {
polyglot?: boolean,
inferPrivate?: boolean,
noPackage?: boolean,
Expand All @@ -12,25 +12,25 @@ declare type DocumentationConfig = {
parseExtension: Array<string>
};

declare type InputsConfig = {
type InputsConfig = {
inputs: Array<SourceFile>,
config: DocumentationConfig
};

declare type CommentError = {
type CommentError = {
message: string,
commentLineNumber?: number
};

declare type DoctrineType = {
type DoctrineType = {
elements?: Array<DoctrineType>,
expression?: DoctrineType,
applications?: Array<DoctrineType>,
type: string,
name?: string
};

declare type CommentLoc = {
type CommentLoc = {
start: {
line: number
},
Expand All @@ -39,12 +39,12 @@ declare type CommentLoc = {
}
};

declare type SourceFile = {
type SourceFile = {
source?: string,
file: string
};

declare type CommentContext = {
type CommentContext = {
sortKey: string,
file: string,
ast: Object,
Expand All @@ -53,12 +53,26 @@ declare type CommentContext = {
github?: CommentContextGitHub
};

declare type CommentContextGitHub = {
type CommentContextGitHub = {
path: string,
url: string
};

declare type CommentTag = {
type CommentTagBase = {
title: string
};

type CommentTag = CommentTagBase & {
name?: string,
title: string,
description?: Object,
default?: any,
lineNumber?: number,
type?: DoctrineType,
properties?: Array<CommentTag>
};

type CommentTagNamed = CommentTag & {
name?: string,
title: string,
description?: Object,
Expand All @@ -68,40 +82,41 @@ declare type CommentTag = {
properties?: Array<CommentTag>
};

declare type CommentMembers = {
type CommentMembers = {
static: Array<Comment>,
instance: Array<Comment>,
events: Array<Comment>,
global: Array<Comment>,
inner: Array<Comment>
};

declare type CommentExample = {
type CommentExample = {
caption?: string,
description?: Object
};

declare type Remark = {
type Remark = {
type: string,
children: Array<Object>
};

declare type Access = 'private' | 'public' | 'protected';
declare type Scope = 'instance' | 'static' | 'inner' | 'global';
declare type Kind = 'class' |
'constant' |
'event' |
'external' |
'file' |
'function' |
'member' |
'mixin' |
'module' |
'namespace' |
'typedef' |
'interface';

declare type Comment = {
type Access = 'private' | 'public' | 'protected';
type Scope = 'instance' | 'static' | 'inner' | 'global';
type Kind =
| 'class'
| 'constant'
| 'event'
| 'external'
| 'file'
| 'function'
| 'member'
| 'mixin'
| 'module'
| 'namespace'
| 'typedef'
| 'interface';

type Comment = {
errors: Array<CommentError>,
tags: Array<CommentTag>,

Expand Down Expand Up @@ -148,8 +163,8 @@ declare type Comment = {
}>
};

declare type ReducedComment = {
type ReducedComment = {
name: string,
kind: ?Kind,
scope?: ?Scope
}
};
4 changes: 2 additions & 2 deletions default_theme/section._
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
= <code><%- param.default %></code><% } %>)</code>
<%= md(param.description, true) %>
</div>
<% if (param.properties) { %>
<% if (param.properties && param.properties.length) { %>
<table class='mt1 mb2 fixed-table h5 col-12'>
<colgroup>
<col width='30%' />
Expand Down Expand Up @@ -93,7 +93,7 @@
<% } %><% if (property.description) {
%>: <%= md(property.description, true) %><%
} %>
<% if (property.properties) { %>
<% if (property.properties && property.properties.length) { %>
<ul>
<% property.properties.forEach(function(property) { %>
<li><code><%- property.name %></code> <%= formatType(property.type) %>
Expand Down
43 changes: 21 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,10 @@ function pipeline() {
};
}



function configure(indexes, args)/*: Promise<InputsConfig> */ {
function configure(indexes, args) /*: Promise<InputsConfig> */ {
let mergedConfig = mergeConfig(args);

return mergedConfig.then(config => {

let expandedInputs = expandInputs(indexes, config);

return expandedInputs.then(inputs => {
Expand All @@ -71,8 +68,10 @@ function configure(indexes, args)/*: Promise<InputsConfig> */ {
* @param {Object} config options
* @returns {Promise<Array<string>>} promise with results
*/
function expandInputs(indexes/*: string|Array<string> */,
config /*: DocumentationConfig */) {
function expandInputs(
indexes /*: string|Array<string> */,
config /*: DocumentationConfig */
) {
// Ensure that indexes is an array of strings
indexes = [].concat(indexes);

Expand All @@ -91,40 +90,42 @@ function buildInternal(inputsAndConfig) {
config.access = ['public', 'undefined', 'protected'];
}

var parseFn = (config.polyglot) ? polyglot : parseJavaScript;
var parseFn = config.polyglot ? polyglot : parseJavaScript;

var buildPipeline = pipeline(
inferName,
inferAccess(config.inferPrivate),
inferAugments,
inferKind,
nest,
inferParams,
inferProperties,
inferReturn,
inferMembership(),
inferType,
nest,
config.github && github,
garbageCollect);
garbageCollect
);

let extractedComments = _.flatMap(inputs, function (sourceFile) {
let extractedComments = _.flatMap(inputs, function(sourceFile) {
if (!sourceFile.source) {
sourceFile.source = fs.readFileSync(sourceFile.file, 'utf8');
}

return parseFn(sourceFile, config).map(buildPipeline);
}).filter(Boolean);

return filterAccess(config.access,
hierarchy(
sort(extractedComments, config)));
return filterAccess(
config.access,
hierarchy(sort(extractedComments, config))
);
}

function lintInternal(inputsAndConfig) {
let inputs = inputsAndConfig.inputs;
let config = inputsAndConfig.config;

let parseFn = (config.polyglot) ? polyglot : parseJavaScript;
let parseFn = config.polyglot ? polyglot : parseJavaScript;

let lintPipeline = pipeline(
lintComments,
Expand All @@ -137,7 +138,8 @@ function lintInternal(inputsAndConfig) {
inferReturn,
inferMembership(),
inferType,
nest);
nest
);

let extractedComments = _.flatMap(inputs, sourceFile => {
if (!sourceFile.source) {
Expand Down Expand Up @@ -183,8 +185,7 @@ function lintInternal(inputsAndConfig) {
* }
* });
*/
let lint = (indexes, args) => configure(indexes, args)
.then(lintInternal);
let lint = (indexes, args) => configure(indexes, args).then(lintInternal);

/**
* Generate JavaScript documentation as a list of parsed JSDoc
Expand Down Expand Up @@ -227,8 +228,7 @@ let lint = (indexes, args) => configure(indexes, args)
* // any other kind of code data.
* });
*/
let build = (indexes, args) => configure(indexes, args)
.then(buildInternal);
let build = (indexes, args) => configure(indexes, args).then(buildInternal);

/**
* Documentation's formats are modular methods that take comments
Expand All @@ -240,9 +240,8 @@ let build = (indexes, args) => configure(indexes, args)
var formats = {
html: require('./lib/output/html'),
md: require('./lib/output/markdown'),
remark: (comments/*: Array<Comment> */, config/*: DocumentationConfig */) =>
markdownAST(comments, config)
.then(res => JSON.stringify(res, null, 2)),
remark: (comments /*: Array<Comment> */, config /*: DocumentationConfig */) =>
markdownAST(comments, config).then(res => JSON.stringify(res, null, 2)),
json: require('./lib/output/json')
};

Expand Down
Loading

0 comments on commit 7374730

Please sign in to comment.