mirror of
https://github.com/status-im/react-native.git
synced 2025-02-05 06:04:15 +00:00
Merge pull request #2517 from sahrens/animatedDocGen
[Docs] Expand API parsing and rendering
This commit is contained in:
commit
2fc8ca01f9
@ -19,6 +19,7 @@ var genericTransform = require('./generic-function-visitor');
|
|||||||
var genericVisitor = genericTransform.visitorList[0];
|
var genericVisitor = genericTransform.visitorList[0];
|
||||||
var traverseFlat = require('./traverseFlat');
|
var traverseFlat = require('./traverseFlat');
|
||||||
var parseTypehint = require('./TypeExpressionParser').parse;
|
var parseTypehint = require('./TypeExpressionParser').parse;
|
||||||
|
var util = require('util');
|
||||||
|
|
||||||
// Don't save object properties source code that is longer than this
|
// Don't save object properties source code that is longer than this
|
||||||
var MAX_PROPERTY_SOURCE_LENGTH = 1000;
|
var MAX_PROPERTY_SOURCE_LENGTH = 1000;
|
||||||
@ -317,6 +318,7 @@ function getObjectData(node, state, source, scopeChain,
|
|||||||
commentsForFile, linesForFile) {
|
commentsForFile, linesForFile) {
|
||||||
var methods = [];
|
var methods = [];
|
||||||
var properties = [];
|
var properties = [];
|
||||||
|
var classes = [];
|
||||||
var superClass = null;
|
var superClass = null;
|
||||||
node.properties.forEach(function(property) {
|
node.properties.forEach(function(property) {
|
||||||
if (property.type === Syntax.SpreadProperty) {
|
if (property.type === Syntax.SpreadProperty) {
|
||||||
@ -341,7 +343,8 @@ function getObjectData(node, state, source, scopeChain,
|
|||||||
scopeChain
|
scopeChain
|
||||||
);
|
);
|
||||||
if (expr) {
|
if (expr) {
|
||||||
if (expr.type === Syntax.FunctionDeclaration) {
|
if (expr.type === Syntax.FunctionDeclaration ||
|
||||||
|
expr.type === Syntax.FunctionExpression) {
|
||||||
var functionData =
|
var functionData =
|
||||||
getFunctionData(expr, property, state, source, commentsForFile,
|
getFunctionData(expr, property, state, source, commentsForFile,
|
||||||
linesForFile);
|
linesForFile);
|
||||||
@ -362,16 +365,24 @@ function getObjectData(node, state, source, scopeChain,
|
|||||||
}
|
}
|
||||||
var docBlock = getDocBlock(property, commentsForFile, linesForFile);
|
var docBlock = getDocBlock(property, commentsForFile, linesForFile);
|
||||||
/* CodexVarDef: modifiers, type, name, default, docblock */
|
/* CodexVarDef: modifiers, type, name, default, docblock */
|
||||||
var propertyData = [
|
if (property.value.type === Syntax.ClassDeclaration) {
|
||||||
['static'],
|
var type = {name: property.value.id.name};
|
||||||
'',
|
var classData = getClassData(property.value, state, source, commentsForFile, linesForFile);
|
||||||
|
classData.ownerProperty = property.key.name;
|
||||||
|
classes.push(classData);
|
||||||
|
} else {
|
||||||
|
var type = {name: property.value.type};
|
||||||
|
}
|
||||||
|
var propertyData = {
|
||||||
// Cast to String because this can be a Number
|
// Cast to String because this can be a Number
|
||||||
// Could also be a String literal (e.g. "key") hence the value
|
// Could also be a String literal (e.g. "key") hence the value
|
||||||
String(property.key.name || property.key.value),
|
name: String(property.key.name || property.key.value),
|
||||||
|
type,
|
||||||
|
docblock: docBlock || '',
|
||||||
|
source: source.substring.apply(source, property.range),
|
||||||
|
modifiers: ['static'],
|
||||||
propertySource,
|
propertySource,
|
||||||
docBlock || '',
|
};
|
||||||
property.loc.start.line
|
|
||||||
];
|
|
||||||
properties.push(propertyData);
|
properties.push(propertyData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -379,6 +390,7 @@ function getObjectData(node, state, source, scopeChain,
|
|||||||
return {
|
return {
|
||||||
methods: methods,
|
methods: methods,
|
||||||
properties: properties,
|
properties: properties,
|
||||||
|
classes: classes,
|
||||||
superClass: superClass
|
superClass: superClass
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -410,6 +422,7 @@ function getClassData(node, state, source, commentsForFile, linesForFile) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
var data = {
|
var data = {
|
||||||
|
name: node.id.name,
|
||||||
methods: methods
|
methods: methods
|
||||||
};
|
};
|
||||||
if (node.superClass && node.superClass.type === Syntax.Identifier) {
|
if (node.superClass && node.superClass.type === Syntax.Identifier) {
|
||||||
|
@ -20,53 +20,52 @@ var slugify = require('slugify');
|
|||||||
|
|
||||||
var styleReferencePattern = /^[^.]+\.propTypes\.style$/;
|
var styleReferencePattern = /^[^.]+\.propTypes\.style$/;
|
||||||
|
|
||||||
var ComponentDoc = React.createClass({
|
function renderType(type) {
|
||||||
renderType: function(type) {
|
if (type.name === 'enum') {
|
||||||
if (type.name === 'enum') {
|
if (typeof type.value === 'string') {
|
||||||
if (typeof type.value === 'string') {
|
|
||||||
return type.value;
|
|
||||||
}
|
|
||||||
return 'enum(' + type.value.map((v => v.value)).join(', ') + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.name === 'shape') {
|
|
||||||
return '{' + Object.keys(type.value).map((key => key + ': ' + this.renderType(type.value[key]))).join(', ') + '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.name == 'union') {
|
|
||||||
return type.value.map(this.renderType).join(', ');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.name === 'arrayOf') {
|
|
||||||
return '[' + this.renderType(type.value) + ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.name === 'instanceOf') {
|
|
||||||
return type.value;
|
return type.value;
|
||||||
}
|
}
|
||||||
|
return 'enum(' + type.value.map((v) => v.value).join(', ') + ')';
|
||||||
|
}
|
||||||
|
|
||||||
if (type.name === 'custom') {
|
if (type.name === 'shape') {
|
||||||
if (styleReferencePattern.test(type.raw)) {
|
return '{' + Object.keys(type.value).map((key => key + ': ' + renderType(type.value[key]))).join(', ') + '}';
|
||||||
var name = type.raw.substring(0, type.raw.indexOf('.'));
|
}
|
||||||
return <a href={slugify(name) + '.html#style'}>{name}#style</a>
|
|
||||||
}
|
if (type.name == 'union') {
|
||||||
if (type.raw === 'EdgeInsetsPropType') {
|
return type.value.map(renderType).join(', ');
|
||||||
return '{top: number, left: number, bottom: number, right: number}';
|
}
|
||||||
}
|
|
||||||
return type.raw;
|
if (type.name === 'arrayOf') {
|
||||||
|
return '[' + renderType(type.value) + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.name === 'instanceOf') {
|
||||||
|
return type.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.name === 'custom') {
|
||||||
|
if (styleReferencePattern.test(type.raw)) {
|
||||||
|
var name = type.raw.substring(0, type.raw.indexOf('.'));
|
||||||
|
return <a href={slugify(name) + '.html#style'}>{name}#style</a>
|
||||||
}
|
}
|
||||||
|
if (type.raw === 'EdgeInsetsPropType') {
|
||||||
if (type.name === 'stylesheet') {
|
return '{top: number, left: number, bottom: number, right: number}';
|
||||||
return 'style';
|
|
||||||
}
|
}
|
||||||
|
return type.raw;
|
||||||
|
}
|
||||||
|
|
||||||
if (type.name === 'func') {
|
if (type.name === 'stylesheet') {
|
||||||
return 'function';
|
return 'style';
|
||||||
}
|
}
|
||||||
|
|
||||||
return type.name;
|
if (type.name === 'func') {
|
||||||
},
|
return 'function';
|
||||||
|
}
|
||||||
|
return type.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ComponentDoc = React.createClass({
|
||||||
renderProp: function(name, prop) {
|
renderProp: function(name, prop) {
|
||||||
return (
|
return (
|
||||||
<div className="prop" key={name}>
|
<div className="prop" key={name}>
|
||||||
@ -77,7 +76,7 @@ var ComponentDoc = React.createClass({
|
|||||||
{name}
|
{name}
|
||||||
{' '}
|
{' '}
|
||||||
{prop.type && <span className="propType">
|
{prop.type && <span className="propType">
|
||||||
{this.renderType(prop.type)}
|
{renderType(prop.type)}
|
||||||
</span>}
|
</span>}
|
||||||
</Header>
|
</Header>
|
||||||
{prop.type && prop.type.name === 'stylesheet' &&
|
{prop.type && prop.type.name === 'stylesheet' &&
|
||||||
@ -128,7 +127,7 @@ var ComponentDoc = React.createClass({
|
|||||||
{name}
|
{name}
|
||||||
{' '}
|
{' '}
|
||||||
{style.props[name].type && <span className="propType">
|
{style.props[name].type && <span className="propType">
|
||||||
{this.renderType(style.props[name].type)}
|
{renderType(style.props[name].type)}
|
||||||
</span>}
|
</span>}
|
||||||
</h6>
|
</h6>
|
||||||
</div>
|
</div>
|
||||||
@ -190,7 +189,6 @@ var ComponentDoc = React.createClass({
|
|||||||
<Marked>
|
<Marked>
|
||||||
{content.description}
|
{content.description}
|
||||||
</Marked>
|
</Marked>
|
||||||
|
|
||||||
<HeaderWithGithub
|
<HeaderWithGithub
|
||||||
title="Props"
|
title="Props"
|
||||||
path={content.filepath}
|
path={content.filepath}
|
||||||
@ -264,7 +262,6 @@ var APIDoc = React.createClass({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
renderMethods: function(methods) {
|
renderMethods: function(methods) {
|
||||||
if (!methods.length) {
|
if (!methods.length) {
|
||||||
return null;
|
return null;
|
||||||
@ -281,6 +278,67 @@ var APIDoc = React.createClass({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderProperty: function(property) {
|
||||||
|
return (
|
||||||
|
<div className="prop" key={property.name}>
|
||||||
|
<Header level={4} className="propTitle" toSlug={property.name}>
|
||||||
|
{property.name}
|
||||||
|
{property.type &&
|
||||||
|
<span className="propType">
|
||||||
|
{': ' + renderType(property.type)}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</Header>
|
||||||
|
{property.docblock && <Marked>
|
||||||
|
{this.removeCommentsFromDocblock(property.docblock)}
|
||||||
|
</Marked>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderProperties: function(properties) {
|
||||||
|
if (!properties || !properties.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<H level={3}>Properties</H>
|
||||||
|
<div className="props">
|
||||||
|
{properties.filter((property) => {
|
||||||
|
return property.name[0] !== '_';
|
||||||
|
}).map(this.renderProperty)}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderClasses: function(classes) {
|
||||||
|
if (!classes || !classes.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<div>
|
||||||
|
{classes.filter((cls) => {
|
||||||
|
return cls.name[0] !== '_' && cls.ownerProperty[0] !== '_';
|
||||||
|
}).map((cls) => {
|
||||||
|
return (
|
||||||
|
<span key={cls.name}>
|
||||||
|
<Header level={2} toSlug={cls.name}>
|
||||||
|
class {cls.name}
|
||||||
|
</Header>
|
||||||
|
<ul>
|
||||||
|
{this.renderMethods(cls.methods)}
|
||||||
|
{this.renderProperties(cls.properties)}
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var content = this.props.content;
|
var content = this.props.content;
|
||||||
if (!content.methods) {
|
if (!content.methods) {
|
||||||
@ -294,6 +352,8 @@ var APIDoc = React.createClass({
|
|||||||
{this.removeCommentsFromDocblock(content.docblock)}
|
{this.removeCommentsFromDocblock(content.docblock)}
|
||||||
</Marked>
|
</Marked>
|
||||||
{this.renderMethods(content.methods)}
|
{this.renderMethods(content.methods)}
|
||||||
|
{this.renderProperties(content.properties)}
|
||||||
|
{this.renderClasses(content.classes)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -371,7 +431,7 @@ var Autodocs = React.createClass({
|
|||||||
var docs = JSON.parse(this.props.children);
|
var docs = JSON.parse(this.props.children);
|
||||||
var content = docs.type === 'component' || docs.type === 'style' ?
|
var content = docs.type === 'component' || docs.type === 'style' ?
|
||||||
<ComponentDoc content={docs} /> :
|
<ComponentDoc content={docs} /> :
|
||||||
<APIDoc content={docs} />;
|
<APIDoc content={docs} apiName={metadata.title} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Site section="docs" title={metadata.title}>
|
<Site section="docs" title={metadata.title}>
|
||||||
|
@ -134,7 +134,7 @@ function renderAPI(type) {
|
|||||||
try {
|
try {
|
||||||
json = jsDocs(fs.readFileSync(filepath).toString());
|
json = jsDocs(fs.readFileSync(filepath).toString());
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error('Cannot parse file', filepath);
|
console.error('Cannot parse file', filepath, e);
|
||||||
json = {};
|
json = {};
|
||||||
}
|
}
|
||||||
return componentsToMarkdown(type, json, filepath, n++);
|
return componentsToMarkdown(type, json, filepath, n++);
|
||||||
@ -187,6 +187,7 @@ var components = [
|
|||||||
var apis = [
|
var apis = [
|
||||||
'../Libraries/ActionSheetIOS/ActionSheetIOS.js',
|
'../Libraries/ActionSheetIOS/ActionSheetIOS.js',
|
||||||
'../Libraries/Utilities/AlertIOS.js',
|
'../Libraries/Utilities/AlertIOS.js',
|
||||||
|
'../Libraries/Animated/Animated.js',
|
||||||
'../Libraries/AppRegistry/AppRegistry.js',
|
'../Libraries/AppRegistry/AppRegistry.js',
|
||||||
'../Libraries/AppStateIOS/AppStateIOS.ios.js',
|
'../Libraries/AppStateIOS/AppStateIOS.ios.js',
|
||||||
'../Libraries/Storage/AsyncStorage.ios.js',
|
'../Libraries/Storage/AsyncStorage.ios.js',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user