Code coverage report for lib/infer/properties.js

Statements: 100% (26 / 26)      Branches: 100% (14 / 14)      Functions: 100% (7 / 7)      Lines: 100% (26 / 26)      Ignored: none     

All files » lib/infer/ » properties.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70    25                       25   25 17 6   11     25 8           8     64         139 4 4     25 6 5 9 8 1   8   8 3             139   139 3     139      
'use strict';
 
var shouldSkipInference = require('./should_skip_inference'),
  finders = require('./finders'),
  flowDoctrine = require('../flow_doctrine');
 
 
/**
 * Infers properties of TypeAlias objects (Flow or TypeScript type definitions)
 *
 * @name inferParams
 * @param {Object} comment parsed comment
 * @returns {Object} comment with inferred properties
 */
module.exports = function () {
 
  function prefixedName(name, prefix) {
    if (prefix.length) {
      return prefix.join('.') + '.' + name;
    }
    return name;
  }
 
  function propertyToDoc(property, prefix) {
    var newProperty = {
      title: 'property',
      name: prefixedName(property.key.name, prefix),
      lineNumber: property.loc.start.line,
      type: flowDoctrine(property.value)
    };
    return newProperty;
  }
 
  return shouldSkipInference(function inferProperties(comment) {
 
 
    // Ensure that explicitly specified properties are not overridden
    // by inferred properties
    var explicitProperties = (comment.properties || []).reduce(function (memo, property) {
      memo[property.name] = true;
      return memo;
    }, {});
 
    function inferProperties(value, prefix) {
      if (value.type === 'ObjectTypeAnnotation') {
        value.properties.forEach(function (property) {
          if (explicitProperties[prefixedName(property.key.name, prefix)] === undefined) {
            if (!comment.properties) {
              comment.properties = [];
            }
            comment.properties = comment.properties.concat(propertyToDoc(property, prefix));
            // Nested type parameters
            if (property.value.type === 'ObjectTypeAnnotation') {
              inferProperties(property.value, prefix.concat(property.key.name));
            }
          }
        });
      }
    }
 
    var node = finders.findType(comment.context.ast, 'TypeAlias');
 
    if (node) {
      inferProperties(node.right, []);
    }
 
    return comment;
  });
};