Skip to content

Commit 62f6648

Browse files
committed
Infer type for variable declarations and class properties
This infers the type from Flow type annotations for variable declarations and class properties. This also moves the logic for setting the `type` for typedefs to the same type inferrer.
1 parent ac5dff2 commit 62f6648

File tree

4 files changed

+94
-33
lines changed

4 files changed

+94
-33
lines changed

index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var fs = require('fs'),
2020
inferMembership = require('./lib/infer/membership'),
2121
inferReturn = require('./lib/infer/return'),
2222
inferAccess = require('./lib/infer/access'),
23-
inferTypedefType = require('./lib/infer/typedef_type'),
23+
inferType = require('./lib/infer/type'),
2424
formatLint = require('./lib/lint').formatLint,
2525
garbageCollect = require('./lib/garbage_collect'),
2626
lintComments = require('./lib/lint').lintComments,
@@ -175,7 +175,7 @@ function buildSync(indexes, options) {
175175
inferProperties(),
176176
inferReturn(),
177177
inferMembership(),
178-
inferTypedefType(),
178+
inferType(),
179179
nest,
180180
options.github && github,
181181
garbageCollect);
@@ -245,7 +245,7 @@ function lint(indexes, options, callback) {
245245
inferProperties(),
246246
inferReturn(),
247247
inferMembership(),
248-
inferTypedefType(),
248+
inferType(),
249249
nest);
250250

251251
return expandInputs(indexes, options, function (error, inputs) {

lib/infer/type.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
var finders = require('./finders'),
4+
shouldSkipInference = require('./should_skip_inference'),
5+
flowDoctrine = require('../flow_doctrine'),
6+
t = require('babel-types');
7+
8+
/**
9+
* Infers type tags by using Flow type annotations
10+
*
11+
* @name inferType
12+
* @param {Object} comment parsed comment
13+
* @returns {Object} comment with type tag inferred
14+
*/
15+
module.exports = function () {
16+
return shouldSkipInference(function inferType(comment) {
17+
if (comment.type) {
18+
return comment;
19+
}
20+
21+
var n = finders.findTarget(comment.context.ast);
22+
if (!n) {
23+
return comment;
24+
}
25+
26+
var type;
27+
switch (n.type) {
28+
case 'VariableDeclarator':
29+
type = n.id.typeAnnotation;
30+
break;
31+
case 'ClassProperty':
32+
type = n.typeAnnotation;
33+
break;
34+
case 'TypeAlias':
35+
type = n.right;
36+
break;
37+
}
38+
if (type) {
39+
if (t.isTypeAnnotation(type)) {
40+
type = type.typeAnnotation;
41+
}
42+
comment.type = flowDoctrine(type);
43+
}
44+
return comment;
45+
});
46+
};

lib/infer/typedef_type.js

-27
This file was deleted.

test/lib/infer/typedef_type.js renamed to test/lib/infer/type.js

+45-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
var test = require('tap').test,
44
parse = require('../../../lib/parsers/javascript'),
55
inferKind = require('../../../lib/infer/kind')(),
6-
inferTypedefType = require('../../../lib/infer/typedef_type')();
6+
inferType = require('../../../lib/infer/type')();
77

88
function toComment(code) {
99
return parse({
@@ -12,10 +12,10 @@ function toComment(code) {
1212
}
1313

1414
function evaluate(code) {
15-
return inferTypedefType(inferKind(toComment(code)));
15+
return inferType(inferKind(toComment(code)));
1616
}
1717

18-
test('inferTypedefType', function (t) {
18+
test('inferType', function (t) {
1919
t.deepEqual(evaluate(
2020
'/** @typedef {T} V */'
2121
).type, {
@@ -64,6 +64,48 @@ test('inferTypedefType', function (t) {
6464
type: 'TypeApplication'
6565
});
6666

67+
t.deepEqual(evaluate(
68+
'/** */' +
69+
'var x: number'
70+
).type, {
71+
name: 'number',
72+
type: 'NameExpression'
73+
});
74+
75+
t.deepEqual(evaluate(
76+
'/** */' +
77+
'let x: number'
78+
).type, {
79+
name: 'number',
80+
type: 'NameExpression'
81+
});
82+
83+
t.deepEqual(evaluate(
84+
'/** */' +
85+
'const x: number = 42;'
86+
).type, {
87+
name: 'number',
88+
type: 'NameExpression'
89+
});
90+
91+
t.deepEqual(evaluate(
92+
'let x,' +
93+
'/** */' +
94+
'y: number'
95+
).type, {
96+
name: 'number',
97+
type: 'NameExpression'
98+
});
99+
100+
t.deepEqual(evaluate(
101+
'class C {' +
102+
'/** */' +
103+
'x: number;' +
104+
'}'
105+
).type, {
106+
name: 'number',
107+
type: 'NameExpression'
108+
});
67109

68110
t.end();
69111
});

0 commit comments

Comments
 (0)