diff --git a/index.js b/index.js index 180f3d95d..570a5a925 100644 --- a/index.js +++ b/index.js @@ -20,7 +20,7 @@ var fs = require('fs'), inferMembership = require('./lib/infer/membership'), inferReturn = require('./lib/infer/return'), inferAccess = require('./lib/infer/access'), - inferTypedefType = require('./lib/infer/typedef_type'), + inferType = require('./lib/infer/type'), formatLint = require('./lib/lint').formatLint, garbageCollect = require('./lib/garbage_collect'), lintComments = require('./lib/lint').lintComments, @@ -175,7 +175,7 @@ function buildSync(indexes, options) { inferProperties(), inferReturn(), inferMembership(), - inferTypedefType(), + inferType(), nest, options.github && github, garbageCollect); @@ -245,7 +245,7 @@ function lint(indexes, options, callback) { inferProperties(), inferReturn(), inferMembership(), - inferTypedefType(), + inferType(), nest); return expandInputs(indexes, options, function (error, inputs) { diff --git a/lib/infer/finders.js b/lib/infer/finders.js index 791cb7afd..394f24ce6 100644 --- a/lib/infer/finders.js +++ b/lib/infer/finders.js @@ -22,9 +22,9 @@ function findTarget(path) { path = path.declaration; } - // var x = TARGET; + // var x = init; if (t.isVariableDeclaration(path)) { - return path.declarations[0].init; + return path.declarations[0]; } // foo.x = TARGET diff --git a/lib/infer/params.js b/lib/infer/params.js index 31278ac71..511a3a9b5 100644 --- a/lib/infer/params.js +++ b/lib/infer/params.js @@ -162,6 +162,12 @@ function inferParams() { return shouldSkipInference(function inferParams(comment) { var node = finders.findTarget(comment.context.ast); + // In case of `/** */ var x = function () {}` findTarget returns + // the declarator. + if (t.isVariableDeclarator(node)) { + node = node.init; + } + if (!t.isFunction(node)) { return comment; } diff --git a/lib/infer/type.js b/lib/infer/type.js new file mode 100644 index 000000000..d9b0004c1 --- /dev/null +++ b/lib/infer/type.js @@ -0,0 +1,55 @@ +'use strict'; + +var finders = require('./finders'), + shouldSkipInference = require('./should_skip_inference'), + flowDoctrine = require('../flow_doctrine'), + t = require('babel-types'); + +var constTypeMapping = { + 'BooleanLiteral': {type: 'BooleanTypeAnnotation'}, + 'NumericLiteral': {type: 'NumberTypeAnnotation'}, + 'StringLiteral': {type: 'StringTypeAnnotation'} +}; + +/** + * Infers type tags by using Flow type annotations + * + * @name inferType + * @param {Object} comment parsed comment + * @returns {Object} comment with type tag inferred + */ +module.exports = function () { + return shouldSkipInference(function inferType(comment) { + if (comment.type) { + return comment; + } + + var n = finders.findTarget(comment.context.ast); + if (!n) { + return comment; + } + + var type; + switch (n.type) { + case 'VariableDeclarator': + type = n.id.typeAnnotation; + if (!type && comment.kind === 'constant') { + type = constTypeMapping[n.init.type]; + } + break; + case 'ClassProperty': + type = n.typeAnnotation; + break; + case 'TypeAlias': + type = n.right; + break; + } + if (type) { + if (t.isTypeAnnotation(type)) { + type = type.typeAnnotation; + } + comment.type = flowDoctrine(type); + } + return comment; + }); +}; diff --git a/lib/infer/typedef_type.js b/lib/infer/typedef_type.js deleted file mode 100644 index b4cb10578..000000000 --- a/lib/infer/typedef_type.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -var shouldSkipInference = require('./should_skip_inference'), - flowDoctrine = require('../flow_doctrine'), - finders = require('./finders'); - -/** - * Infers the type of typedefs defined by Flow type aliases - * - * @name inferTypedefType - * @param {Object} comment parsed comment - * @returns {Object} comment with type tag inferred - */ -module.exports = function () { - return shouldSkipInference(function inferTypedefType(comment) { - if (comment.kind !== 'typedef') { - return comment; - } - - var flowAlias = finders.findTarget(comment.context.ast); - if (flowAlias && flowAlias.type === 'TypeAlias') { - comment.type = flowDoctrine(flowAlias.right); - } - - return comment; - }); -}; diff --git a/test/lib/infer/params.js b/test/lib/infer/params.js index 4f48dae76..b318918c4 100644 --- a/test/lib/infer/params.js +++ b/test/lib/infer/params.js @@ -21,6 +21,22 @@ test('inferParams', function (t) { function f(x) {} }).params, [{lineNumber: 3, name: 'x', title: 'param'}]); + t.deepEqual(evaluate(function () { + /** Test */ + var f = function (x) {}; + }).params, [{lineNumber: 3, name: 'x', title: 'param'}]); + + t.deepEqual(evaluate('/** Test */ var f = (x) => {}').params, + [{lineNumber: 1, name: 'x', title: 'param'}]); + + t.deepEqual(evaluate(function () { + var x = 1, + g = function (y) {}, + /** Test */ + f = function (x) {}; + }).params, [{lineNumber: 5, name: 'x', title: 'param'}]); + + t.deepEqual(evaluate('/** Test */ export function f(x) {}').params, [{lineNumber: 1, name: 'x', title: 'param'}]); diff --git a/test/lib/infer/type.js b/test/lib/infer/type.js new file mode 100644 index 000000000..6777d79dc --- /dev/null +++ b/test/lib/infer/type.js @@ -0,0 +1,135 @@ +'use strict'; + +var test = require('tap').test, + parse = require('../../../lib/parsers/javascript'), + inferKind = require('../../../lib/infer/kind')(), + inferType = require('../../../lib/infer/type')(); + +function toComment(code) { + return parse({ + source: code + })[0]; +} + +function evaluate(code) { + return inferType(inferKind(toComment(code))); +} + +test('inferType', function (t) { + t.deepEqual(evaluate( + '/** @typedef {T} V */' + ).type, { + name: 'T', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + '/** */' + + 'type V = T' + ).type, { + name: 'T', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + '/** @typedef {Array} V */' + ).type, { + applications: [ + { + name: 'T', + type: 'NameExpression' + } + ], + expression: { + name: 'Array', + type: 'NameExpression' + }, + type: 'TypeApplication' + }); + + t.deepEqual(evaluate( + '/** */' + + 'type V = Array' + ).type, { + applications: [ + { + name: 'T', + type: 'NameExpression' + } + ], + expression: { + name: 'Array', + type: 'NameExpression' + }, + type: 'TypeApplication' + }); + + t.deepEqual(evaluate( + '/** */' + + 'var x: number' + ).type, { + name: 'number', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + '/** */' + + 'let x: number' + ).type, { + name: 'number', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + '/** */' + + 'const x: number = 42;' + ).type, { + name: 'number', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + 'let x,' + + '/** */' + + 'y: number' + ).type, { + name: 'number', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + 'class C {' + + '/** */' + + 'x: number;' + + '}' + ).type, { + name: 'number', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + '/** */' + + 'const x = 42;' + ).type, { + name: 'number', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + '/** */' + + 'const x = "abc";' + ).type, { + name: 'string', + type: 'NameExpression' + }); + + t.deepEqual(evaluate( + '/** */' + + 'const x = true;' + ).type, { + name: 'boolean', + type: 'NameExpression' + }); + + t.end(); +}); diff --git a/test/lib/infer/typedef_type.js b/test/lib/infer/typedef_type.js deleted file mode 100644 index 070ec5ed6..000000000 --- a/test/lib/infer/typedef_type.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict'; - -var test = require('tap').test, - parse = require('../../../lib/parsers/javascript'), - inferKind = require('../../../lib/infer/kind')(), - inferTypedefType = require('../../../lib/infer/typedef_type')(); - -function toComment(code) { - return parse({ - source: code - })[0]; -} - -function evaluate(code) { - return inferTypedefType(inferKind(toComment(code))); -} - -test('inferTypedefType', function (t) { - t.deepEqual(evaluate( - '/** @typedef {T} V */' - ).type, { - name: 'T', - type: 'NameExpression' - }); - - t.deepEqual(evaluate( - '/** */' + - 'type V = T' - ).type, { - name: 'T', - type: 'NameExpression' - }); - - t.deepEqual(evaluate( - '/** @typedef {Array} V */' - ).type, { - applications: [ - { - name: 'T', - type: 'NameExpression' - } - ], - expression: { - name: 'Array', - type: 'NameExpression' - }, - type: 'TypeApplication' - }); - - t.deepEqual(evaluate( - '/** */' + - 'type V = Array' - ).type, { - applications: [ - { - name: 'T', - type: 'NameExpression' - } - ], - expression: { - name: 'Array', - type: 'NameExpression' - }, - type: 'TypeApplication' - }); - - - t.end(); -}); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy