Skip to content

Commit 7c00acc

Browse files
authored
fix(flow): Fix inference of Flow types with properties (#751)
Previously we naively thought that id.name would be a string for all types, which is not the case. Instead, we use babel-generator to safely generate string representations of types. Fixes #749
1 parent cfaaf21 commit 7c00acc

8 files changed

+396
-20
lines changed

lib/flow_doctrine.js

+30-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
22
/* @flow */
33

4+
const generate = require('babel-generator').default;
5+
46
var namedTypes = {
57
NumberTypeAnnotation: 'number',
68
BooleanTypeAnnotation: 'boolean',
@@ -14,12 +16,6 @@ var oneToOne = {
1416
VoidTypeAnnotation: 'VoidLiteral'
1517
};
1618

17-
var literalTypes = {
18-
BooleanLiteralTypeAnnotation: 'BooleanLiteralType',
19-
NumericLiteralTypeAnnotation: 'NumericLiteralType',
20-
StringLiteralTypeAnnotation: 'StringLiteralType'
21-
};
22-
2319
function propertyToField(property) {
2420
var type = flowDoctrine(property.value);
2521
if (property.optional) {
@@ -116,15 +112,19 @@ function flowDoctrine(type /*: Object */) /*: DoctrineType*/ {
116112
type: 'TypeApplication',
117113
expression: {
118114
type: 'NameExpression',
119-
name: type.id.name
115+
name: generate(type.id, {
116+
compact: true
117+
}).code
120118
},
121119
applications: type.typeParameters.params.map(flowDoctrine)
122120
};
123121
}
124122

125123
return {
126124
type: 'NameExpression',
127-
name: type.id.name
125+
name: generate(type.id, {
126+
compact: true
127+
}).code
128128
};
129129

130130
case 'ObjectTypeAnnotation':
@@ -137,20 +137,30 @@ function flowDoctrine(type /*: Object */) /*: DoctrineType*/ {
137137

138138
return {
139139
type: 'NameExpression',
140-
name: type.id.name
140+
name: generate(type.id, {
141+
compact: true
142+
}).code
143+
};
144+
case 'BooleanLiteralTypeAnnotation':
145+
return {
146+
type: 'BooleanLiteralType',
147+
value: type.value
148+
};
149+
case 'NumericLiteralTypeAnnotation':
150+
return {
151+
type: 'NumericLiteralType',
152+
value: type.value
153+
};
154+
case 'StringLiteralTypeAnnotation':
155+
return {
156+
type: 'StringLiteralType',
157+
value: type.value
158+
};
159+
default:
160+
return {
161+
type: 'AllLiteral'
141162
};
142163
}
143-
144-
if (type.type in literalTypes) {
145-
return {
146-
type: literalTypes[type.type],
147-
value: type.value
148-
};
149-
}
150-
151-
return {
152-
type: 'AllLiteral'
153-
};
154164
}
155165

156166
module.exports = flowDoctrine;

test/fixture/es6.input.js

+5
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,8 @@ export function isArrayEqualWith<T>(
154154
): boolean {
155155
return true;
156156
}
157+
158+
/** Regression check for #749 */
159+
export function paramWithMemberType(a: atype.property): boolean {
160+
return true;
161+
}

test/fixture/es6.output-toc.md

+10
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,13 @@ Regression check for #498
138138
- `compareFunction` **function (a: T, b: T): [boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** (optional, default `(a:T,b:T):boolean=>a===b`)
139139

140140
Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
141+
142+
## paramWithMemberType
143+
144+
Regression check for #749
145+
146+
**Parameters**
147+
148+
- `a` **atype.property**
149+
150+
Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**

test/fixture/es6.output.json

+120
Original file line numberDiff line numberDiff line change
@@ -2841,5 +2841,125 @@
28412841
}
28422842
],
28432843
"namespace": "isArrayEqualWith"
2844+
},
2845+
{
2846+
"description": {
2847+
"type": "root",
2848+
"children": [
2849+
{
2850+
"type": "paragraph",
2851+
"children": [
2852+
{
2853+
"type": "text",
2854+
"value": "Regression check for #749",
2855+
"position": {
2856+
"start": {
2857+
"line": 1,
2858+
"column": 1,
2859+
"offset": 0
2860+
},
2861+
"end": {
2862+
"line": 1,
2863+
"column": 26,
2864+
"offset": 25
2865+
},
2866+
"indent": []
2867+
}
2868+
}
2869+
],
2870+
"position": {
2871+
"start": {
2872+
"line": 1,
2873+
"column": 1,
2874+
"offset": 0
2875+
},
2876+
"end": {
2877+
"line": 1,
2878+
"column": 26,
2879+
"offset": 25
2880+
},
2881+
"indent": []
2882+
}
2883+
}
2884+
],
2885+
"position": {
2886+
"start": {
2887+
"line": 1,
2888+
"column": 1,
2889+
"offset": 0
2890+
},
2891+
"end": {
2892+
"line": 1,
2893+
"column": 26,
2894+
"offset": 25
2895+
}
2896+
}
2897+
},
2898+
"tags": [],
2899+
"loc": {
2900+
"start": {
2901+
"line": 158,
2902+
"column": 0
2903+
},
2904+
"end": {
2905+
"line": 158,
2906+
"column": 32
2907+
}
2908+
},
2909+
"context": {
2910+
"loc": {
2911+
"start": {
2912+
"line": 159,
2913+
"column": 0
2914+
},
2915+
"end": {
2916+
"line": 161,
2917+
"column": 1
2918+
}
2919+
}
2920+
},
2921+
"augments": [],
2922+
"errors": [],
2923+
"examples": [],
2924+
"params": [
2925+
{
2926+
"title": "param",
2927+
"name": "a",
2928+
"lineNumber": 159,
2929+
"type": {
2930+
"type": "NameExpression",
2931+
"name": "atype.property"
2932+
}
2933+
}
2934+
],
2935+
"properties": [],
2936+
"returns": [
2937+
{
2938+
"title": "returns",
2939+
"type": {
2940+
"type": "NameExpression",
2941+
"name": "boolean"
2942+
}
2943+
}
2944+
],
2945+
"sees": [],
2946+
"throws": [],
2947+
"todos": [],
2948+
"name": "paramWithMemberType",
2949+
"kind": "function",
2950+
"members": {
2951+
"global": [],
2952+
"inner": [],
2953+
"instance": [],
2954+
"events": [],
2955+
"static": []
2956+
},
2957+
"path": [
2958+
{
2959+
"name": "paramWithMemberType",
2960+
"kind": "function"
2961+
}
2962+
],
2963+
"namespace": "paramWithMemberType"
28442964
}
28452965
]

test/fixture/es6.output.md

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
- [iAmPublic](#iampublic)
2323
- [execute](#execute)
2424
- [isArrayEqualWith](#isarrayequalwith)
25+
- [paramWithMemberType](#paramwithmembertype)
2526

2627
## destructure
2728

@@ -161,3 +162,13 @@ Regression check for #498
161162
- `compareFunction` **function (a: T, b: T): [boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** (optional, default `(a:T,b:T):boolean=>a===b`)
162163

163164
Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
165+
166+
## paramWithMemberType
167+
168+
Regression check for #749
169+
170+
**Parameters**
171+
172+
- `a` **atype.property**
173+
174+
Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**

test/fixture/es6.output.md.json

+120
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,126 @@
22432243
}
22442244
]
22452245
},
2246+
{
2247+
"type": "paragraph",
2248+
"children": [
2249+
{
2250+
"type": "text",
2251+
"value": "Returns "
2252+
},
2253+
{
2254+
"type": "strong",
2255+
"children": [
2256+
{
2257+
"href": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
2258+
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
2259+
"type": "link",
2260+
"children": [
2261+
{
2262+
"type": "text",
2263+
"value": "boolean"
2264+
}
2265+
]
2266+
}
2267+
]
2268+
},
2269+
{
2270+
"type": "text",
2271+
"value": " "
2272+
}
2273+
]
2274+
},
2275+
{
2276+
"depth": 2,
2277+
"type": "heading",
2278+
"children": [
2279+
{
2280+
"type": "text",
2281+
"value": "paramWithMemberType"
2282+
}
2283+
]
2284+
},
2285+
{
2286+
"type": "paragraph",
2287+
"children": [
2288+
{
2289+
"type": "text",
2290+
"value": "Regression check for #749",
2291+
"position": {
2292+
"start": {
2293+
"line": 1,
2294+
"column": 1,
2295+
"offset": 0
2296+
},
2297+
"end": {
2298+
"line": 1,
2299+
"column": 26,
2300+
"offset": 25
2301+
},
2302+
"indent": []
2303+
}
2304+
}
2305+
],
2306+
"position": {
2307+
"start": {
2308+
"line": 1,
2309+
"column": 1,
2310+
"offset": 0
2311+
},
2312+
"end": {
2313+
"line": 1,
2314+
"column": 26,
2315+
"offset": 25
2316+
},
2317+
"indent": []
2318+
}
2319+
},
2320+
{
2321+
"type": "strong",
2322+
"children": [
2323+
{
2324+
"type": "text",
2325+
"value": "Parameters"
2326+
}
2327+
]
2328+
},
2329+
{
2330+
"ordered": false,
2331+
"type": "list",
2332+
"children": [
2333+
{
2334+
"type": "listItem",
2335+
"children": [
2336+
{
2337+
"type": "paragraph",
2338+
"children": [
2339+
{
2340+
"type": "inlineCode",
2341+
"value": "a"
2342+
},
2343+
{
2344+
"type": "text",
2345+
"value": " "
2346+
},
2347+
{
2348+
"type": "strong",
2349+
"children": [
2350+
{
2351+
"type": "text",
2352+
"value": "atype.property"
2353+
}
2354+
]
2355+
},
2356+
{
2357+
"type": "text",
2358+
"value": " "
2359+
}
2360+
]
2361+
}
2362+
]
2363+
}
2364+
]
2365+
},
22462366
{
22472367
"type": "paragraph",
22482368
"children": [

test/format_type.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ test('formatType', function(t) {
2222
['null', 'null'],
2323
['null', 'null'],
2424
['*', 'any'],
25+
['namedType.typeProperty', 'namedType.typeProperty'],
2526
[
2627
'Array|undefined',
2728
'([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \\| [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined))'

0 commit comments

Comments
 (0)