Improve doc generation with flow types
Reviewed By: vjeux, hramos Differential Revision: D4638610 fbshipit-source-id: 122d6fb68d521b675019a0698b6427960bb2d070
This commit is contained in:
parent
e70cdf0cc1
commit
a7a3922b89
|
@ -12,15 +12,16 @@
|
|||
'use strict';
|
||||
|
||||
var DocsSidebar = require('DocsSidebar');
|
||||
var Footer = require('Footer');
|
||||
var Header = require('Header');
|
||||
var HeaderWithGithub = require('HeaderWithGithub');
|
||||
var Footer = require('Footer');
|
||||
var Marked = require('Marked');
|
||||
var Metadata = require('Metadata');
|
||||
var Prism = require('Prism');
|
||||
var React = require('React');
|
||||
var Site = require('Site');
|
||||
|
||||
var slugify = require('slugify');
|
||||
var Metadata = require('Metadata');
|
||||
|
||||
var styleReferencePattern = /^[^.]+\.propTypes\.style$/;
|
||||
|
||||
|
@ -33,6 +34,10 @@ function renderEnumValue(value) {
|
|||
}
|
||||
|
||||
function renderType(type) {
|
||||
return <code>{(type.nullable ? '?' : '') + renderBaseType(type)}</code>;
|
||||
}
|
||||
|
||||
function renderBaseType(type) {
|
||||
if (type.name === 'enum') {
|
||||
if (typeof type.value === 'string') {
|
||||
return type.value;
|
||||
|
@ -92,7 +97,7 @@ function renderType(type) {
|
|||
return type.raw;
|
||||
}
|
||||
|
||||
return type.name;
|
||||
return type.raw || type.name;
|
||||
}
|
||||
|
||||
function renderTypeNameLink(typeName, docPath, namedTypes) {
|
||||
|
@ -121,7 +126,7 @@ function renderTypeWithLinks(type, docTitle, namedTypes) {
|
|||
<div>
|
||||
{
|
||||
type.names.map((typeName, index, array) => {
|
||||
let separator = index < array.length - 1 && ' | ';
|
||||
const separator = index < array.length - 1 && ' | ';
|
||||
return (
|
||||
<span key={index}>
|
||||
{renderTypeNameLink(typeName, docPath, namedTypes)}
|
||||
|
@ -176,7 +181,7 @@ function removeCommentsFromDocblock(docblock) {
|
|||
}
|
||||
|
||||
function getNamedTypes(typedefs) {
|
||||
let namedTypes = {};
|
||||
const namedTypes = {};
|
||||
typedefs && typedefs.forEach(typedef => {
|
||||
if (typedef.name) {
|
||||
const type = typedef.name.toLowerCase();
|
||||
|
@ -195,9 +200,9 @@ var ComponentDoc = React.createClass({
|
|||
<span className="platform">{platform}</span>
|
||||
)}
|
||||
{name}
|
||||
{' '}
|
||||
{prop.type && <span className="propType">
|
||||
{renderType(prop.type)}
|
||||
{prop.required ? ': ' : '?: '}
|
||||
{(prop.type || prop.flowType) && <span className="propType">
|
||||
{renderType(prop.flowType || prop.type)}
|
||||
</span>}
|
||||
</Header>
|
||||
{prop.deprecationMessage && <div className="deprecated">
|
||||
|
@ -428,9 +433,9 @@ var APIDoc = React.createClass({
|
|||
<div className="prop" key={property.name}>
|
||||
<Header level={4} className="propTitle" toSlug={property.name}>
|
||||
{property.name}
|
||||
{property.type &&
|
||||
{(property.type || property.flowType) &&
|
||||
<span className="propType">
|
||||
{': ' + renderType(property.type)}
|
||||
{': ' + renderType(property.flowType || property.type)}
|
||||
</span>
|
||||
}
|
||||
</Header>
|
||||
|
@ -654,13 +659,14 @@ var Method = React.createClass({
|
|||
</span> || ''}
|
||||
{this.props.name}
|
||||
<span className="methodType">
|
||||
({this.props.params && this.props.params.length && this.props.params
|
||||
({(this.props.params && this.props.params.length && this.props.params
|
||||
.map((param) => {
|
||||
var res = param.name;
|
||||
res += param.optional ? '?' : '';
|
||||
param.type && param.type.names && (res += ': ' + param.type.names.join(', '));
|
||||
return res;
|
||||
})
|
||||
.join(', ')})
|
||||
.join(', ')) || ''})
|
||||
{this.props.returns && ': ' + this.renderTypehint(this.props.returns.type)}
|
||||
</span>
|
||||
</Header>
|
||||
|
@ -805,7 +811,7 @@ var Modal = React.createClass({
|
|||
<div className="modal-content">
|
||||
<button className="modal-button-close">×</button>
|
||||
<div className="center">
|
||||
<iframe className="simulator" src={url} width="256" height="550" frameborder="0" scrolling="no"></iframe>
|
||||
<iframe className="simulator" src={url} width="256" height="550" frameborder="0" scrolling="no" />
|
||||
<p>Powered by <a target="_blank" href="https://appetize.io">appetize.io</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
const docgen = require('react-docgen');
|
||||
|
||||
|
@ -18,18 +27,18 @@ function stylePropTypeHandler(documentation, path) {
|
|||
docgen.utils.getPropertyName(propertyPath) !== 'style') {
|
||||
return;
|
||||
}
|
||||
let valuePath = docgen.utils.resolveToValue(propertyPath.get('value'));
|
||||
const valuePath = docgen.utils.resolveToValue(propertyPath.get('value'));
|
||||
// If it's a call to StyleSheetPropType, do stuff
|
||||
if (valuePath.node.type !== 'CallExpression' ||
|
||||
valuePath.node.callee.name !== 'StyleSheetPropType') {
|
||||
return;
|
||||
}
|
||||
// Get type of style sheet
|
||||
let styleSheetModule = docgen.utils.resolveToModule(
|
||||
const styleSheetModule = docgen.utils.resolveToModule(
|
||||
valuePath.get('arguments', 0)
|
||||
);
|
||||
if (styleSheetModule) {
|
||||
let propDescriptor = documentation.getPropDescriptor('style');
|
||||
const propDescriptor = documentation.getPropDescriptor('style');
|
||||
propDescriptor.type = {name: 'stylesheet', value: styleSheetModule};
|
||||
}
|
||||
});
|
||||
|
@ -48,13 +57,13 @@ function deprecatedPropTypeHandler(documentation, path) {
|
|||
|
||||
// Checks for deprecatedPropType function and add deprecation info.
|
||||
propTypesPath.get('properties').each(function(propertyPath) {
|
||||
let valuePath = docgen.utils.resolveToValue(propertyPath.get('value'));
|
||||
const valuePath = docgen.utils.resolveToValue(propertyPath.get('value'));
|
||||
// If it's a call to deprecatedPropType, do stuff
|
||||
if (valuePath.node.type !== 'CallExpression' ||
|
||||
valuePath.node.callee.name !== 'deprecatedPropType') {
|
||||
return;
|
||||
}
|
||||
let propDescriptor = documentation.getPropDescriptor(
|
||||
const propDescriptor = documentation.getPropDescriptor(
|
||||
docgen.utils.getPropertyName(propertyPath)
|
||||
);
|
||||
// The 2nd argument of deprecatedPropType is the deprecation message.
|
||||
|
@ -78,7 +87,7 @@ function typedefHandler(documentation, path) {
|
|||
|
||||
// Name, type, description of the typedef
|
||||
const name = declarationPath.value.id.name;
|
||||
const type = { names: [typePath.node.id.name] };
|
||||
const type = { names: [typePath.node.id ? typePath.node.id.name : typePath.node.type] };
|
||||
const description = docgen.utils.docblock.getDocblock(path);
|
||||
|
||||
// Get the properties for the typedef
|
||||
|
@ -108,7 +117,7 @@ function typedefHandler(documentation, path) {
|
|||
});
|
||||
}
|
||||
|
||||
let typedef = {
|
||||
const typedef = {
|
||||
name: name,
|
||||
description: description,
|
||||
type: type,
|
||||
|
@ -134,7 +143,7 @@ function getTypeName(type) {
|
|||
}
|
||||
|
||||
function jsDocFormatType(entities) {
|
||||
let modEntities = entities;
|
||||
const modEntities = entities;
|
||||
if (entities) {
|
||||
if (typeof entities === 'object' && entities.length) {
|
||||
entities.map((entity, entityIndex) => {
|
||||
|
@ -155,7 +164,7 @@ function jsDocFormatHandler(documentation, path) {
|
|||
if (!methods || methods.length === 0) {
|
||||
return;
|
||||
}
|
||||
let modMethods = methods;
|
||||
const modMethods = methods;
|
||||
methods.map((method, methodIndex) => {
|
||||
modMethods[methodIndex].params = jsDocFormatType(method.params);
|
||||
modMethods[methodIndex].returns = jsDocFormatType(method.returns);
|
||||
|
@ -184,8 +193,8 @@ function findExportedObject(ast, recast) {
|
|||
// handler.
|
||||
// This converts any expression, e.g. `foo` to an object expression of
|
||||
// the form `{propTypes: foo}`
|
||||
let b = recast.types.builders;
|
||||
let nt = recast.types.namedTypes;
|
||||
const b = recast.types.builders;
|
||||
const nt = recast.types.namedTypes;
|
||||
let obj = objPath.node;
|
||||
|
||||
// Hack: This is converting calls like
|
||||
|
@ -215,7 +224,7 @@ function findExportedObject(ast, recast) {
|
|||
}
|
||||
|
||||
function findExportedType(ast, recast) {
|
||||
let types = recast.types.namedTypes;
|
||||
const types = recast.types.namedTypes;
|
||||
let definitions;
|
||||
recast.visit(ast, {
|
||||
visitExportNamedDeclaration: function(path) {
|
||||
|
|
|
@ -1362,6 +1362,7 @@ div[data-twttr-id] iframe {
|
|||
padding: 3px 10px; }
|
||||
|
||||
.propType {
|
||||
font-family: 'source-code-pro', Menlo, 'Courier New', Consolas, monospace;
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
white-space: pre-wrap; }
|
||||
|
|
|
@ -1193,6 +1193,7 @@ div[data-twttr-id] iframe {
|
|||
}
|
||||
|
||||
.propType {
|
||||
font-family: 'source-code-pro', Menlo, 'Courier New', Consolas, monospace;
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
white-space: pre-wrap;
|
||||
|
|
Loading…
Reference in New Issue