text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
  
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  
  var _AbstractSyntaxLoader2 = require('typhonjs-escomplex-commons/dist/module/plugin/syntax/AbstractSyntaxLoader');
  
  var _AbstractSyntaxLoader3 = _interopRequireDefault(_AbstractSyntaxLoader2);
  
  var _ASTParser = require('typhonjs-escomplex-commons/dist/utils/ast/ASTParser');
  
  var _ASTParser2 = _interopRequireDefault(_ASTParser);
  
  var _TraitUtil = require('typhonjs-escomplex-commons/dist/module/traits/TraitUtil');
  
  var _TraitUtil2 = _interopRequireDefault(_TraitUtil);
  
  var _actualize = require('typhonjs-escomplex-commons/dist/module/traits/actualize');
  
  var _actualize2 = _interopRequireDefault(_actualize);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  
  /**
   * Provides an typhonjs-escomplex-module / ESComplexModule plugin which loads syntax definitions for trait resolution
   * for all ESTree AST nodes up to and including ES6.
   *
   * @see https://www.npmjs.com/package/typhonjs-escomplex-module
   */
  var PluginSyntaxESTree = function (_AbstractSyntaxLoader) {
    _inherits(PluginSyntaxESTree, _AbstractSyntaxLoader);
  
    function PluginSyntaxESTree() {
      _classCallCheck(this, PluginSyntaxESTree);
  
      return _possibleConstructorReturn(this, Object.getPrototypeOf(PluginSyntaxESTree).apply(this, arguments));
    }
  
    _createClass(PluginSyntaxESTree, [{
      key: 'onConfigure',
  
      // ESComplexModule plugin callbacks ------------------------------------------------------------------------------
  
      /**
       * Loads any default settings that are not already provided by any user options.
       *
       * @param {object}   ev - escomplex plugin event data.
       *
       * The following options are:
       * ```
       * (boolean)   commonjs - Boolean indicating that source code being processed is CommonJS; defaults to false.
       *
       * (function)  dependencyResolver - Provides a function to resolve dynamic dependencies; defaults to undefined.
       *
       * (boolean)   forin - Boolean indicating whether for...in / for...of loops should be considered a source of
       *                     cyclomatic complexity; defaults to false.
       *
       * (boolean)   logicalor - Boolean indicating whether operator || should be considered a source of cyclomatic
       *                         complexity; defaults to true.
       *
       * (boolean)   switchcase - Boolean indicating whether switch statements should be considered a source of cyclomatic
       *                          complexity; defaults to true.
       *
       * (boolean)   trycatch - Boolean indicating whether catch clauses should be considered a source of cyclomatic
       *                        complexity; defaults to false.
       * ```
       */
      value: function onConfigure(ev) {
        ev.data.settings.commonjs = typeof ev.data.options.commonjs === 'boolean' ? ev.data.options.commonjs : false;
        ev.data.settings.dependencyResolver = typeof ev.data.options.dependencyResolver === 'function' ? ev.data.options.dependencyResolver : void 0;
        ev.data.settings.forin = typeof ev.data.options.forin === 'boolean' ? ev.data.options.forin : false;
        ev.data.settings.logicalor = typeof ev.data.options.logicalor === 'boolean' ? ev.data.options.logicalor : true;
        ev.data.settings.switchcase = typeof ev.data.options.switchcase === 'boolean' ? ev.data.options.switchcase : true;
        ev.data.settings.trycatch = typeof ev.data.options.trycatch === 'boolean' ? ev.data.options.trycatch : false;
      }
  
      // Core / ES5 ESTree AST nodes -----------------------------------------------------------------------------------
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#arrayexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ArrayExpression',
      value: function ArrayExpression() {
        return (0, _actualize2.default)(0, 0, function (node) {
          var operators = ['[]'];
          if (Array.isArray(node.elements) && node.elements.length > 0) // Add length - 1 commas
            {
              operators.push.apply(operators, _toConsumableArray(new Array(node.elements.length - 1).fill(',')));
            }
          return operators;
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#assignmentexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'AssignmentExpression',
      value: function AssignmentExpression() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.operator;
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#blockstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'BlockStatement',
      value: function BlockStatement() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#binaryexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'BinaryExpression',
      value: function BinaryExpression() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.operator;
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#breakstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'BreakStatement',
      value: function BreakStatement() {
        return (0, _actualize2.default)(1, 0, 'break');
      }
  
      /**
       * ES5 Node
       *
       * Processes CommonJS dependencies if settings.commonjs is set to true. An optional function
       * settings.dependencyResolver may be used to resolve dynamic dependencies.
        * @param {object}   settings - escomplex settings
       *
       * @see https://github.com/estree/estree/blob/master/spec.md#callexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'CallExpression',
      value: function CallExpression(settings) {
        return (0, _actualize2.default)(function (node) // lloc
        {
          return node.callee.type === 'FunctionExpression' ? 1 : 0;
        }, 0, // cyclomatic
        '()', // operators
        void 0, // operands
        void 0, // ignoreKeys
        void 0, // newScope
        function (node) {
          // Only process CJS dependencies if settings.commonjs is true.
          if (settings.commonjs && node.callee.type === 'Identifier' && node.callee.name === 'require' && node.arguments.length === 1) {
            var dependency = node.arguments[0];
  
            var dependencyPath = '* dynamic dependency *';
  
            if (dependency.type === 'Literal' || dependency.type === 'StringLiteral') {
              dependencyPath = typeof settings.dependencyResolver === 'function' ? settings.dependencyResolver(dependency.value) : dependency.value;
            }
  
            return { line: node.loc.start.line, path: dependencyPath, type: 'cjs' };
          }
        });
      }
  
      /**
       * ES5 Node
       * @param {object}   settings - escomplex settings
       * @see https://github.com/estree/estree/blob/master/spec.md#catchclause
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'CatchClause',
      value: function CatchClause(settings) {
        return (0, _actualize2.default)(1, function () {
          return settings.trycatch ? 1 : 0;
        }, 'catch');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#conditionalexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ConditionalExpression',
      value: function ConditionalExpression() {
        return (0, _actualize2.default)(0, 1, ':?');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#continuestatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ContinueStatement',
      value: function ContinueStatement() {
        return (0, _actualize2.default)(1, 0, 'continue');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#dowhilestatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'DoWhileStatement',
      value: function DoWhileStatement() {
        return (0, _actualize2.default)(2, function (node) {
          return node.test ? 1 : 0;
        }, 'dowhile');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#emptystatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'EmptyStatement',
      value: function EmptyStatement() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#expressionstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ExpressionStatement',
      value: function ExpressionStatement() {
        return (0, _actualize2.default)(1, 0);
      }
  
      /**
       * ES5 Node
       * @param {object}   settings - escomplex settings
       * @see https://github.com/estree/estree/blob/master/spec.md#forinstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ForInStatement',
      value: function ForInStatement(settings) {
        return (0, _actualize2.default)(1, function () {
          return settings.forin ? 1 : 0;
        }, 'forin');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#forstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ForStatement',
      value: function ForStatement() {
        return (0, _actualize2.default)(1, function (node) {
          return node.test ? 1 : 0;
        }, 'for');
      }
  
      /**
       * ES5 Node
       *
       * Note: The function name (node.id) is returned as an operand and excluded from traversal as to not be included in
       * the function operand calculations.
       *
       * @see https://github.com/estree/estree/blob/master/spec.md#functiondeclaration
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'FunctionDeclaration',
      value: function FunctionDeclaration() {
        return (0, _actualize2.default)(1, 0, function (node, parent) {
          var operators = parent && parent.type === 'MethodDefinition' && typeof parent.computed === 'boolean' && parent.computed ? [].concat(_toConsumableArray(_ASTParser2.default.parse(parent.key).operators)) : [];
  
          operators.push(typeof node.generator === 'boolean' && node.generator ? 'function*' : 'function');
          return operators;
        }, function (node, parent) {
          return s_SAFE_COMPUTED_OPERANDS(node, parent);
        }, 'id', function (node, parent) {
          return {
            type: 'method',
            name: s_SAFE_COMPUTED_NAME(node, parent),
            lineStart: node.loc.start.line,
            lineEnd: node.loc.end.line,
            paramCount: node.params.length
          };
        });
      }
  
      /**
       * ES5 Node
       *
       * Note: The function name (node.id) is returned as an operand and excluded from traversal as to not be included in
       * the function operand calculations.
       *
       * @see https://github.com/estree/estree/blob/master/spec.md#functionexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'FunctionExpression',
      value: function FunctionExpression() {
        return (0, _actualize2.default)(0, 0, function (node, parent) {
          var operators = parent && parent.type === 'MethodDefinition' && typeof parent.computed === 'boolean' && parent.computed ? [].concat(_toConsumableArray(_ASTParser2.default.parse(parent.key).operators)) : [];
  
          operators.push(typeof node.generator === 'boolean' && node.generator ? 'function*' : 'function');
          return operators;
        }, function (node, parent) {
          return s_SAFE_COMPUTED_OPERANDS(node, parent);
        }, 'id', function (node, parent) {
          return {
            type: 'method',
            name: s_SAFE_COMPUTED_NAME(node, parent),
            lineStart: node.loc.start.line,
            lineEnd: node.loc.end.line,
            paramCount: node.params.length
          };
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#identifier
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'Identifier',
      value: function Identifier() {
        return (0, _actualize2.default)(0, 0, void 0, function (node) {
          return node.name;
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#ifstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'IfStatement',
      value: function IfStatement() {
        return (0, _actualize2.default)(function (node) {
          return node.alternate ? 2 : 1;
        }, 1, ['if', { identifier: 'else', filter: function filter(node) {
            return !!node.alternate;
          } }]);
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#labeledstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'LabeledStatement',
      value: function LabeledStatement() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES5 Node
       *
       * Avoid conflicts between string literals and identifiers.
       *
       * @see https://github.com/estree/estree/blob/master/spec.md#literal
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'Literal',
      value: function Literal() {
        return (0, _actualize2.default)(0, 0, void 0, function (node) {
          var operands = [];
  
          if (_typeof(node.regex) === 'object' && typeof node.raw !== 'undefined') {
            operands.push(node.raw);
          } else {
            operands.push(typeof node.value === 'string' ? '"' + node.value + '"' : node.value);
          }
  
          return operands;
        });
      }
  
      /**
       * ES5 Node
       * @param {object}   settings - escomplex settings
       * @see https://github.com/estree/estree/blob/master/spec.md#logicalexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'LogicalExpression',
      value: function LogicalExpression(settings) {
        return (0, _actualize2.default)(0, function (node) {
          var isAnd = node.operator === '&&';
          var isOr = node.operator === '||';
          return isAnd || settings.logicalor && isOr ? 1 : 0;
        }, function (node) {
          return node.operator;
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#memberexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'MemberExpression',
      value: function MemberExpression() {
        return (0, _actualize2.default)(function (node) {
          return ['ObjectExpression', 'ArrayExpression', 'FunctionExpression'].indexOf(node.object.type) === -1 ? 0 : 1;
        }, 0, function (node) {
          return typeof node.computed === 'boolean' && node.computed ? '[]' : '.';
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#newexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'NewExpression',
      value: function NewExpression() {
        return (0, _actualize2.default)(function (node) {
          return node.callee.type === 'FunctionExpression' ? 1 : 0;
        }, 0, 'new');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#objectexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ObjectExpression',
      value: function ObjectExpression() {
        return (0, _actualize2.default)(0, 0, '{}');
      }
  
      /**
       * ES5 Node
       *
       * Note that w/ ES6+ `:` may be omitted and the Property node defines `shorthand` to indicate this case.
       *
       * @see https://github.com/estree/estree/blob/master/spec.md#property
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'Property',
      value: function Property() {
        return (0, _actualize2.default)(1, 0, function (node) {
          return typeof node.shorthand === 'undefined' ? ':' : typeof node.shorthand === 'boolean' && !node.shorthand ? ':' : void 0;
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#returnstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ReturnStatement',
      value: function ReturnStatement() {
        return (0, _actualize2.default)(1, 0, 'return');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#sequenceexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'SequenceExpression',
      value: function SequenceExpression() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES5 Node
       * @param {object}   settings - escomplex settings
       * @see https://github.com/estree/estree/blob/master/spec.md#switchcase
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'SwitchCase',
      value: function SwitchCase(settings) {
        return (0, _actualize2.default)(1, function (node) {
          return settings.switchcase && node.test ? 1 : 0;
        }, function (node) {
          return node.test ? 'case' : 'default';
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#switchstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'SwitchStatement',
      value: function SwitchStatement() {
        return (0, _actualize2.default)(1, 0, 'switch');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#thisexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ThisExpression',
      value: function ThisExpression() {
        return (0, _actualize2.default)(0, 0, 'this');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#throwstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ThrowStatement',
      value: function ThrowStatement() {
        return (0, _actualize2.default)(1, 0, 'throw');
      }
  
      /**
       * ES5 Node
       *
       * Note: esprima has duplicate nodes the catch block; `handler` is the actual ESTree spec.
       *
       * @see https://github.com/estree/estree/blob/master/spec.md#trystatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'TryStatement',
      value: function TryStatement() {
        return (0, _actualize2.default)(1, 0, function (node) {
          return node.finalizer ? ['try', 'finally'] : ['try'];
        }, void 0, ['guardedHandlers', 'handlers']);
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#unaryexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'UnaryExpression',
      value: function UnaryExpression() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.operator + ' (' + (node.prefix ? 'pre' : 'post') + 'fix)';
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#updateexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'UpdateExpression',
      value: function UpdateExpression() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.operator + ' (' + (node.prefix ? 'pre' : 'post') + 'fix)';
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#variabledeclaration
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'VariableDeclaration',
      value: function VariableDeclaration() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.kind;
        });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#variabledeclarator
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'VariableDeclarator',
      value: function VariableDeclarator() {
        return (0, _actualize2.default)(1, 0, { identifier: '=', filter: function filter(node) {
            return !!node.init;
          } });
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#whilestatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'WhileStatement',
      value: function WhileStatement() {
        return (0, _actualize2.default)(1, function (node) {
          return node.test ? 1 : 0;
        }, 'while');
      }
  
      /**
       * ES5 Node
       * @see https://github.com/estree/estree/blob/master/spec.md#withstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'WithStatement',
      value: function WithStatement() {
        return (0, _actualize2.default)(1, 0, 'with');
      }
  
      // ES6 ESTree AST nodes ------------------------------------------------------------------------------------------
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#assignmentpattern
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'AssignmentPattern',
      value: function AssignmentPattern() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.operator;
        }, void 0, function (node) {
          return node.left.type === 'MemberExpression' ? _TraitUtil2.default.safeName(node.left.object) + '.' + node.left.property.name : typeof node.left.id !== 'undefined' ? _TraitUtil2.default.safeName(node.left.id) : _TraitUtil2.default.safeName(node.left);
        });
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#arraypattern
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ArrayPattern',
      value: function ArrayPattern() {
        return (0, _actualize2.default)(0, 0, function (node) {
          var operators = ['[]'];
          if (Array.isArray(node.elements) && node.elements.length > 0) // Add length - 1 commas
            {
              operators.push.apply(operators, _toConsumableArray(new Array(node.elements.length - 1).fill(',')));
            }
          return operators;
        });
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#arrowfunctionexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ArrowFunctionExpression',
      value: function ArrowFunctionExpression() {
        return (0, _actualize2.default)(0, 0, 'function=>', void 0, void 0, function (node) {
          return {
            type: 'method',
            name: _TraitUtil2.default.safeName(node),
            lineStart: node.loc.start.line,
            lineEnd: node.loc.end.line,
            paramCount: node.params.length
          };
        });
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#classbody
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ClassBody',
      value: function ClassBody() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#classdeclaration
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ClassDeclaration',
      value: function ClassDeclaration() {
        return (0, _actualize2.default)(1, 0, 'class', void 0, void 0, function (node) {
          return {
            type: 'class',
            name: _TraitUtil2.default.safeName(node.id),
            lineStart: node.loc.start.line,
            lineEnd: node.loc.end.line
          };
        });
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#classexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ClassExpression',
      value: function ClassExpression() {
        return (0, _actualize2.default)(1, 0, 'class', void 0, void 0, function (node) {
          return {
            type: 'class',
            name: _TraitUtil2.default.safeName(node.id),
            lineStart: node.loc.start.line,
            lineEnd: node.loc.end.line
          };
        });
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#exportalldeclaration
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ExportAllDeclaration',
      value: function ExportAllDeclaration() {
        return (0, _actualize2.default)(0, 0, ['export', '*']);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#exportdefaultdeclaration
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ExportDefaultDeclaration',
      value: function ExportDefaultDeclaration() {
        return (0, _actualize2.default)(0, 0, ['export', 'default']);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#exportnameddeclaration
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ExportNamedDeclaration',
      value: function ExportNamedDeclaration() {
        return (0, _actualize2.default)(0, 0, ['export', '{}']);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#exportspecifier
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ExportSpecifier',
      value: function ExportSpecifier() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.exported.name === node.local.name ? void 0 : 'as';
        });
      }
  
      /**
       * ES6 Node
       * @param {object}   settings - escomplex settings
       * @see https://github.com/estree/estree/blob/master/es6.md#forofstatement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ForOfStatement',
      value: function ForOfStatement(settings) {
        return (0, _actualize2.default)(1, function () {
          return settings.forin ? 1 : 0;
        }, 'forof');
      }
  
      /**
       * ES6 Node
       * @param {object}   settings - escomplex settings
       * @see https://github.com/estree/estree/blob/master/es6.md#importdeclaration
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ImportDeclaration',
      value: function ImportDeclaration(settings) {
        return (0, _actualize2.default)(0, 0, ['import', 'from'], void 0, void 0, void 0, function (node) {
          var dependencyPath = typeof settings.dependencyResolver === 'function' ? settings.dependencyResolver(node.source.value) : node.source.value;
  
          return { line: node.source.loc.start.line, path: dependencyPath, type: 'esm' };
        });
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#importdefaultspecifier
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ImportDefaultSpecifier',
      value: function ImportDefaultSpecifier() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#importnamespacespecifier
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ImportNamespaceSpecifier',
      value: function ImportNamespaceSpecifier() {
        return (0, _actualize2.default)(0, 0, ['import', '*', 'as']);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#importspecifier
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ImportSpecifier',
      value: function ImportSpecifier() {
        return (0, _actualize2.default)(0, 0, function (node) {
          return node.imported.name === node.local.name ? '{}' : ['{}', 'as'];
        });
      }
  
      /**
       * ES6 Node
       *
       * Note: esprima doesn't follow the ESTree spec and `meta` & `property` are strings instead of Identifier nodes.
       *
       * @see https://github.com/estree/estree/blob/master/es6.md#metaproperty
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'MetaProperty',
      value: function MetaProperty() {
        return (0, _actualize2.default)(0, 0, '.', function (node) {
          return typeof node.meta === 'string' && typeof node.property === 'string' ? [node.meta, node.property] : void 0;
        });
      }
  
      /**
       * ES6 Node
       *
       * Note: must skip as the following FunctionExpression assigns the name.
       *
       * @see https://github.com/estree/estree/blob/master/es6.md#methoddefinition
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'MethodDefinition',
      value: function MethodDefinition() {
        return (0, _actualize2.default)(0, 0, function (node) {
          var operators = [];
          if (node.kind && (node.kind === 'get' || node.kind === 'set')) {
            operators.push(node.kind);
          }
          if (typeof node.static === 'boolean' && node.static) {
            operators.push('static');
          }
          return operators;
        }, void 0, 'key');
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#objectpattern
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'ObjectPattern',
      value: function ObjectPattern() {
        return (0, _actualize2.default)(0, 0, '{}');
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#restelement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'RestElement',
      value: function RestElement() {
        return (0, _actualize2.default)(0, 0, '... (rest)');
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#spreadelement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'SpreadElement',
      value: function SpreadElement() {
        return (0, _actualize2.default)(0, 0, '... (spread)');
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#super
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'Super',
      value: function Super() {
        return (0, _actualize2.default)(0, 0, void 0, 'super');
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#taggedtemplateexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'TaggedTemplateExpression',
      value: function TaggedTemplateExpression() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#templateelement
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'TemplateElement',
      value: function TemplateElement() {
        return (0, _actualize2.default)(0, 0, void 0, function (node) {
          return node.value.cooked !== '' ? node.value.cooked : void 0;
        });
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#templateliteral
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'TemplateLiteral',
      value: function TemplateLiteral() {
        return (0, _actualize2.default)(0, 0);
      }
  
      /**
       * ES6 Node
       * @see https://github.com/estree/estree/blob/master/es6.md#yieldexpression
       * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}}
       */
  
    }, {
      key: 'YieldExpression',
      value: function YieldExpression() {
        return (0, _actualize2.default)(1, 0, function (node) {
          return typeof node.delegate === 'boolean' && node.delegate ? 'yield*' : 'yield';
        });
      }
    }]);
  
    return PluginSyntaxESTree;
  }(_AbstractSyntaxLoader3.default);
  
  /**
   * Provides a utility method that determines the name of a method for ESTree / Babylon AST nodes. For ESTree the
   * parent node must be accessed for class methods. If the name is a computed value and not a string literal then
   * `astParse` is invoked to determine the computed name and is output as `<computed~${computed expression}>`.
   *
   * Note; ESTree has a parent node which defines the method name with a child FunctionExpression /
   * FunctionDeclaration. Babylon AST only has ClassMethod with a child `key` providing the method name.
   *
   * @param {object}   node - The current AST node.
   * @param {object}   parent - The parent AST node.
   *
   * @returns {string}
   */
  
  
  exports.default = PluginSyntaxESTree;
  function s_SAFE_COMPUTED_NAME(node, parent) {
    var name = void 0;
  
    // Handle ESTree case.
    if (parent && parent.type === 'MethodDefinition') {
      if (typeof parent.computed === 'boolean' && parent.computed) {
        // The following will pick up a single literal computed value (string); expressions return
        // `<computed>`.
        name = parent.key.type === 'Literal' ? _TraitUtil2.default.safeValue(parent.key) : '<computed~' + _ASTParser2.default.parse(parent.key).source + '>';
      } else // Parent is not computed and `parent.key` is an `Identifier` node.
        {
          name = _TraitUtil2.default.safeName(parent.key);
        }
    }
  
    // Last chance assignment handles other node types / expressions: arrow, yield, etc.
    if (typeof name !== 'string') {
      name = _TraitUtil2.default.safeName(node.id || node.key);
    }
  
    return name;
  }
  
  /**
   * Provides a utility method that determines the operands of a method for ESTree AST nodes. For ESTree the
   * parent node must be accessed for class methods. If the name is a computed value and not a string literal then
   * `astParse` is invoked to determine the computed operands.
   *
   * Note; ESTree has a parent node which defines the method name with a child FunctionExpression /
   * FunctionDeclaration. Babylon AST only has ClassMethod with a child `key` providing the method name.
   *
   * @param {object}   node - The current AST node.
   * @param {object}   parent - The parent AST node.
   *
   * @returns {Array<*>}
   */
  function s_SAFE_COMPUTED_OPERANDS(node, parent) {
    var operands = [];
  
    if (parent && parent.type === 'MethodDefinition') {
      if (typeof parent.computed === 'boolean' && parent.computed) {
        // The following will pick up a single literal computed value (string).
        if (parent.key.type === 'Literal') {
          operands.push(_TraitUtil2.default.safeValue(parent.key));
        } else // Fully evaluate AST node and children for computed operands.
          {
            operands.push.apply(operands, _toConsumableArray(_ASTParser2.default.parse(parent.key).operands));
          }
      } else // Parent is not computed and `parent.key` is an `Identifier` node.
        {
          operands.push(_TraitUtil2.default.safeName(parent.key));
        }
    }
  
    if (operands.length === 0) {
      operands.push(_TraitUtil2.default.safeName(node.id || node.key));
    }
  
    return operands;
  }
  module.exports = exports['default'];