Skip to content

Commit 7730af7

Browse files
committed
Implement flow type inference
cc @thejameskyle `lib/flow_doctrine.js` is where we convert Babel-parsed Flow annotations into doctrine-style objects so they can be formatted with all of the existing helpers.
1 parent 6545f3e commit 7730af7

File tree

8 files changed

+701
-3
lines changed

8 files changed

+701
-3
lines changed

lib/flow_doctrine.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
var namedTypes = {
2+
'NumberTypeAnnotation': 'number',
3+
'BooleanTypeAnnotation': 'boolean',
4+
'StringTypeAnnotation': 'string'
5+
};
6+
7+
var oneToOne = {
8+
'AnyTypeAnnotation': {
9+
type: 'AllLiteral'
10+
}
11+
};
12+
13+
function flowDoctrine(type) {
14+
15+
if (type.type in namedTypes) {
16+
return {
17+
type: 'NameExpression',
18+
name: namedTypes[type.type]
19+
};
20+
}
21+
22+
if (type.type in oneToOne) {
23+
return oneToOne[type.type];
24+
}
25+
26+
if (type.type === 'NullableTypeAnnotation') {
27+
return {
28+
type: 'OptionalType',
29+
expression: flowDoctrine(type.typeAnnotation)
30+
};
31+
}
32+
33+
if (type.type === 'UnionTypeAnnotation') {
34+
return {
35+
type: 'UnionType',
36+
elements: type.types.map(flowDoctrine)
37+
};
38+
}
39+
40+
if (type.type === 'GenericTypeAnnotation') {
41+
42+
if (type.typeParameters) {
43+
return {
44+
type: 'TypeApplication',
45+
expression: {
46+
type: 'NameExpression',
47+
name: type.id.name
48+
},
49+
applications: type.typeParameters.params.map(flowDoctrine)
50+
};
51+
}
52+
53+
return {
54+
type: 'NameExpression',
55+
name: type.id.name
56+
};
57+
}
58+
}
59+
60+
module.exports = flowDoctrine;

lib/infer/params.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

3-
var types = require('ast-types');
3+
var types = require('ast-types'),
4+
flowDoctrine = require('../flow_doctrine');
45

56
/**
67
* Infers param tags by reading function parameter names
@@ -29,11 +30,15 @@ module.exports = function inferParams(comment) {
2930
if (!comment.params) {
3031
comment.params = [];
3132
}
32-
comment.params.push({
33+
var newParam = {
3334
title: 'param',
3435
name: param.name,
3536
lineNumber: param.loc.start.line
36-
});
37+
};
38+
if (param.typeAnnotation && param.typeAnnotation.typeAnnotation) {
39+
newParam.type = flowDoctrine(param.typeAnnotation.typeAnnotation);
40+
}
41+
comment.params.push(newParam);
3742
}
3843
paramOrder[param.name] = i++;
3944
});

test/fixture/flow-types.input.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* eslint-disable */
2+
3+
/**
4+
* This function returns the number one.
5+
*/
6+
function addThem(a: number, b: string, c: ?boolean, d: Array<number>, e: Object, f: Named) {
7+
return a + b + c + d + e;
8+
};
9+
10+
/* eslint-enable */
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# addThem
2+
3+
This function returns the number one.
4+
5+
6+
**Parameters**
7+
8+
- `a` **number**
9+
10+
- `b` **string**
11+
12+
- `c` **[boolean]**
13+
14+
- `d` **Array<number>**
15+
16+
- `e` **Object**
17+
18+
- `f` **Named**
19+
20+
21+

test/fixture/flow-types.output.json

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
[
2+
{
3+
"description": "This function returns the number one.",
4+
"tags": [],
5+
"loc": {
6+
"start": {
7+
"line": 3,
8+
"column": 0
9+
},
10+
"end": {
11+
"line": 5,
12+
"column": 3
13+
}
14+
},
15+
"context": {
16+
"loc": {
17+
"start": {
18+
"line": 6,
19+
"column": 0
20+
},
21+
"end": {
22+
"line": 8,
23+
"column": 1
24+
}
25+
},
26+
"code": "/* eslint-disable */\n\n/**\n * This function returns the number one.\n */\nfunction addThem(a: number, b: string, c: ?boolean, d: Array<number>, e: Object, f: Named) {\n return a + b + c + d + e;\n};\n\n/* eslint-enable */\n"
27+
},
28+
"errors": [],
29+
"name": "addThem",
30+
"kind": "function",
31+
"params": [
32+
{
33+
"title": "param",
34+
"name": "a",
35+
"lineNumber": 6,
36+
"type": {
37+
"type": "NameExpression",
38+
"name": "number"
39+
}
40+
},
41+
{
42+
"title": "param",
43+
"name": "b",
44+
"lineNumber": 6,
45+
"type": {
46+
"type": "NameExpression",
47+
"name": "string"
48+
}
49+
},
50+
{
51+
"title": "param",
52+
"name": "c",
53+
"lineNumber": 6,
54+
"type": {
55+
"type": "OptionalType",
56+
"expression": {
57+
"type": "NameExpression",
58+
"name": "boolean"
59+
}
60+
}
61+
},
62+
{
63+
"title": "param",
64+
"name": "d",
65+
"lineNumber": 6,
66+
"type": {
67+
"type": "TypeApplication",
68+
"expression": {
69+
"type": "NameExpression",
70+
"name": "Array"
71+
},
72+
"applications": [
73+
{
74+
"type": "NameExpression",
75+
"name": "number"
76+
}
77+
]
78+
}
79+
},
80+
{
81+
"title": "param",
82+
"name": "e",
83+
"lineNumber": 6,
84+
"type": {
85+
"type": "NameExpression",
86+
"name": "Object"
87+
}
88+
},
89+
{
90+
"title": "param",
91+
"name": "f",
92+
"lineNumber": 6,
93+
"type": {
94+
"type": "NameExpression",
95+
"name": "Named"
96+
}
97+
}
98+
],
99+
"members": {
100+
"instance": [],
101+
"static": []
102+
},
103+
"events": [],
104+
"path": [
105+
"addThem"
106+
]
107+
}
108+
]

test/fixture/flow-types.output.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# addThem
2+
3+
This function returns the number one.
4+
5+
6+
**Parameters**
7+
8+
- `a` **number**
9+
10+
- `b` **string**
11+
12+
- `c` **[boolean]**
13+
14+
- `d` **Array<number>**
15+
16+
- `e` **Object**
17+
18+
- `f` **Named**
19+
20+
21+

0 commit comments

Comments
 (0)