Skip to content

Commit

Permalink
fix(flow): Fix inference of Flow types with properties (#751)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tmcw committed Apr 24, 2017
1 parent cfaaf21 commit 7c00acc
Show file tree
Hide file tree
Showing 8 changed files with 396 additions and 20 deletions.
50 changes: 30 additions & 20 deletions lib/flow_doctrine.js
@@ -1,6 +1,8 @@
'use strict';
/* @flow */

const generate = require('babel-generator').default;

var namedTypes = {
NumberTypeAnnotation: 'number',
BooleanTypeAnnotation: 'boolean',
Expand All @@ -14,12 +16,6 @@ var oneToOne = {
VoidTypeAnnotation: 'VoidLiteral'
};

var literalTypes = {
BooleanLiteralTypeAnnotation: 'BooleanLiteralType',
NumericLiteralTypeAnnotation: 'NumericLiteralType',
StringLiteralTypeAnnotation: 'StringLiteralType'
};

function propertyToField(property) {
var type = flowDoctrine(property.value);
if (property.optional) {
Expand Down Expand Up @@ -116,15 +112,19 @@ function flowDoctrine(type /*: Object */) /*: DoctrineType*/ {
type: 'TypeApplication',
expression: {
type: 'NameExpression',
name: type.id.name
name: generate(type.id, {
compact: true
}).code
},
applications: type.typeParameters.params.map(flowDoctrine)
};
}

return {
type: 'NameExpression',
name: type.id.name
name: generate(type.id, {
compact: true
}).code
};

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

return {
type: 'NameExpression',
name: type.id.name
name: generate(type.id, {
compact: true
}).code
};
case 'BooleanLiteralTypeAnnotation':
return {
type: 'BooleanLiteralType',
value: type.value
};
case 'NumericLiteralTypeAnnotation':
return {
type: 'NumericLiteralType',
value: type.value
};
case 'StringLiteralTypeAnnotation':
return {
type: 'StringLiteralType',
value: type.value
};
default:
return {
type: 'AllLiteral'
};
}

if (type.type in literalTypes) {
return {
type: literalTypes[type.type],
value: type.value
};
}

return {
type: 'AllLiteral'
};
}

module.exports = flowDoctrine;
5 changes: 5 additions & 0 deletions test/fixture/es6.input.js
Expand Up @@ -154,3 +154,8 @@ export function isArrayEqualWith<T>(
): boolean {
return true;
}

/** Regression check for #749 */
export function paramWithMemberType(a: atype.property): boolean {
return true;
}
10 changes: 10 additions & 0 deletions test/fixture/es6.output-toc.md
Expand Up @@ -138,3 +138,13 @@ Regression check for #498
- `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`)

Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**

## paramWithMemberType

Regression check for #749

**Parameters**

- `a` **atype.property**

Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
120 changes: 120 additions & 0 deletions test/fixture/es6.output.json
Expand Up @@ -2841,5 +2841,125 @@
}
],
"namespace": "isArrayEqualWith"
},
{
"description": {
"type": "root",
"children": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"value": "Regression check for #749",
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 26,
"offset": 25
},
"indent": []
}
}
],
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 26,
"offset": 25
},
"indent": []
}
}
],
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 26,
"offset": 25
}
}
},
"tags": [],
"loc": {
"start": {
"line": 158,
"column": 0
},
"end": {
"line": 158,
"column": 32
}
},
"context": {
"loc": {
"start": {
"line": 159,
"column": 0
},
"end": {
"line": 161,
"column": 1
}
}
},
"augments": [],
"errors": [],
"examples": [],
"params": [
{
"title": "param",
"name": "a",
"lineNumber": 159,
"type": {
"type": "NameExpression",
"name": "atype.property"
}
}
],
"properties": [],
"returns": [
{
"title": "returns",
"type": {
"type": "NameExpression",
"name": "boolean"
}
}
],
"sees": [],
"throws": [],
"todos": [],
"name": "paramWithMemberType",
"kind": "function",
"members": {
"global": [],
"inner": [],
"instance": [],
"events": [],
"static": []
},
"path": [
{
"name": "paramWithMemberType",
"kind": "function"
}
],
"namespace": "paramWithMemberType"
}
]
11 changes: 11 additions & 0 deletions test/fixture/es6.output.md
Expand Up @@ -22,6 +22,7 @@
- [iAmPublic](#iampublic)
- [execute](#execute)
- [isArrayEqualWith](#isarrayequalwith)
- [paramWithMemberType](#paramwithmembertype)

## destructure

Expand Down Expand Up @@ -161,3 +162,13 @@ Regression check for #498
- `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`)

Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**

## paramWithMemberType

Regression check for #749

**Parameters**

- `a` **atype.property**

Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
120 changes: 120 additions & 0 deletions test/fixture/es6.output.md.json
Expand Up @@ -2243,6 +2243,126 @@
}
]
},
{
"type": "paragraph",
"children": [
{
"type": "text",
"value": "Returns "
},
{
"type": "strong",
"children": [
{
"href": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
"type": "link",
"children": [
{
"type": "text",
"value": "boolean"
}
]
}
]
},
{
"type": "text",
"value": " "
}
]
},
{
"depth": 2,
"type": "heading",
"children": [
{
"type": "text",
"value": "paramWithMemberType"
}
]
},
{
"type": "paragraph",
"children": [
{
"type": "text",
"value": "Regression check for #749",
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 26,
"offset": 25
},
"indent": []
}
}
],
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 26,
"offset": 25
},
"indent": []
}
},
{
"type": "strong",
"children": [
{
"type": "text",
"value": "Parameters"
}
]
},
{
"ordered": false,
"type": "list",
"children": [
{
"type": "listItem",
"children": [
{
"type": "paragraph",
"children": [
{
"type": "inlineCode",
"value": "a"
},
{
"type": "text",
"value": " "
},
{
"type": "strong",
"children": [
{
"type": "text",
"value": "atype.property"
}
]
},
{
"type": "text",
"value": " "
}
]
}
]
}
]
},
{
"type": "paragraph",
"children": [
Expand Down
1 change: 1 addition & 0 deletions test/format_type.js
Expand Up @@ -22,6 +22,7 @@ test('formatType', function(t) {
['null', 'null'],
['null', 'null'],
['*', 'any'],
['namedType.typeProperty', 'namedType.typeProperty'],
[
'Array|undefined',
'([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))'
Expand Down

0 comments on commit 7c00acc

Please sign in to comment.