UNPKG

eslint-traverser

Version:

A utility that helps traverse code the way ESLint does

129 lines (111 loc) 4.1 kB
'use strict'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var uniqueId = require('lodash/uniqueId'); var iteratee = require('lodash/iteratee'); var constant = require('lodash/constant'); var isFunction = require('lodash/isFunction'); var noop = require('lodash/noop'); var mapValues = require('lodash/mapValues'); var assign = require('lodash/assign'); var every = require('lodash/every'); function throwMessage(message) { throw Error(message); } var MISSING_TYPE = 'Missing mandatory parameter - type - Must be a String'; var MISSING_CB = 'Missing mandatory parameter - cb - Must be a Function'; var getRestParams = function getRestParams(rest) { var cb = rest.pop(); if (!isFunction(cb)) { throwMessage(MISSING_CB); } var matches = iteratee(rest.pop() || constant(true)); return { cb: cb, matches: matches }; }; var runOneTimeRule = function runOneTimeRule(code, config, rule) { var linter = require('eslint').linter; var ruleId = uniqueId(); linter.defineRule(ruleId, rule); var actualConfig = assign({}, config, { rules: _defineProperty({}, ruleId, 2), parserOptions: assign({ ecmaVersion: 6 }, config.parserOptions) }); linter.verify(code, actualConfig); }; var runOneTimeRuleForType = function runOneTimeRuleForType(code, config, type, logic) { runOneTimeRule(code, config, function (context) { return _defineProperty({}, type, function (node) { logic(node, context); }); }); }; function isParserOption(key) { return key === 'ecmaVersion' || key === 'sourceType' || key === 'ecmaFeatures'; } function isOnlyParserOptions(config) { return every(Object.keys(config), isParserOption); } module.exports = function (code) { var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (isOnlyParserOptions(config)) { config = { parserOptions: config }; } if (!code) { throw Error('Code must be a string.'); } if (config.rules) { throw Error('Do not specify rules in the config.'); } return { get: function get() { var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : throwMessage(MISSING_TYPE); for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { rest[_key - 1] = arguments[_key]; } var _getRestParams = getRestParams(rest); var cb = _getRestParams.cb; var matches = _getRestParams.matches; runOneTimeRuleForType(code, config, type, function (node, context) { if (matches(node)) { cb(node, context); } }); }, first: function first() { var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : throwMessage(MISSING_TYPE); for (var _len2 = arguments.length, rest = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { rest[_key2 - 1] = arguments[_key2]; } var _getRestParams2 = getRestParams(rest); var cb = _getRestParams2.cb; var matches = _getRestParams2.matches; var found = false; runOneTimeRuleForType(code, config, type, function (node, context) { if (matches(node) && !found) { found = true; cb(node, context); } }); }, runRuleCode: function runRuleCode(rule) { runOneTimeRule(code, config, rule); }, visitAll: function visitAll() { var visitors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var cb = arguments[1]; if (!isFunction(cb)) { throwMessage(MISSING_CB); } var origExitVisitor = visitors['Program:exit'] || noop; runOneTimeRule(code, config, function (context) { return assign({}, visitors, { 'Program:exit': function ProgramExit(node) { origExitVisitor(node); cb(node, context); } }); }); } }; };