UNPKG

escomplex-plugin-syntax-babylon

Version:

Provides a plugin for typhonjs-escomplex module processing which loads syntax definitions for trait resolution for Babylon AST.

396 lines (323 loc) 15.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _PluginSyntaxESTree2 = require('escomplex-plugin-syntax-estree/dist/PluginSyntaxESTree'); var _PluginSyntaxESTree3 = _interopRequireDefault(_PluginSyntaxESTree2); var _ASTGenerator = require('typhonjs-escomplex-commons/dist/utils/ast/ASTGenerator'); var _ASTGenerator2 = _interopRequireDefault(_ASTGenerator); var _HalsteadArray = require('typhonjs-escomplex-commons/dist/module/traits/HalsteadArray'); var _HalsteadArray2 = _interopRequireDefault(_HalsteadArray); 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 }; } /** * Provides an typhonjs-escomplex-module / ESComplexModule plugin which loads syntax definitions for trait resolution * for unique Babylon AST not found in ESTree. * * @see https://www.npmjs.com/package/typhonjs-escomplex-module */ var PluginSyntaxBabylon = function (_PluginSyntaxESTree) { (0, _inherits3.default)(PluginSyntaxBabylon, _PluginSyntaxESTree); function PluginSyntaxBabylon() { (0, _classCallCheck3.default)(this, PluginSyntaxBabylon); return (0, _possibleConstructorReturn3.default)(this, (PluginSyntaxBabylon.__proto__ || (0, _getPrototypeOf2.default)(PluginSyntaxBabylon)).apply(this, arguments)); } (0, _createClass3.default)(PluginSyntaxBabylon, [{ key: 'BindExpression', // Unique Babylon AST nodes -------------------------------------------------------------------------------------- /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#bindexpression * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ value: function BindExpression() { return (0, _actualize2.default)(0, 0); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#booleanliteral * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'BooleanLiteral', value: function BooleanLiteral() { return (0, _actualize2.default)(0, 0, undefined, function (node) { return node.value; }); } // /** // * @see https://github.com/babel/babylon/blob/master/ast/spec.md#classmethod // * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} // */ // ClassMethod() // { // return actualize(1, 0, (node) => // { // const operators = typeof node.computed === 'boolean' && node.computed ? // [...ASTGenerator.parse(node.key).operators] : []; // // if (node.kind && (node.kind === 'get' || node.kind === 'set')) { operators.push(node.kind); } // if (typeof node.async === 'boolean' && node.async) { operators.push('async'); } // if (typeof node.static === 'boolean' && node.static) { operators.push('static'); } // // if (typeof node.generator === 'boolean' && node.generator) // { // operators.push('function*'); // } // // return operators; // }, // (node, parent) => { return s_SAFE_COMPUTED_OPERANDS(node, parent); }, // 'key', // Note: must skip key as the assigned name is determined above. // (node) => // { // let name; // // if (typeof node.computed === 'boolean' && node.computed) // { // name = node.key.type === 'StringLiteral' ? TraitUtil.safeValue(node.key) : // `<computed~${ASTGenerator.parse(node.key).source}>`; // } // else // ClassMethod is not computed and is an `Identifier` node. // { // name = TraitUtil.safeName(node.key); // } // // return { // type: 'method', // name, // lineStart: node.loc.start.line, // lineEnd: node.loc.end.line, // paramCount: node.params.length // }; // }); // } /** * Note: logical SLOC for the method declaration should be incremented by the module metric processor. * * @see https://github.com/babel/babylon/blob/master/ast/spec.md#classmethod * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'ClassMethod', value: function ClassMethod() { return (0, _actualize2.default)(0, 0, void 0, void 0, ['key', 'params'], // Note: skip key & params as name / operands / operators are calculated in new scope below. function (node, parent) { var name = void 0; var operands = []; var operators = []; if (node.kind && (node.kind === 'get' || node.kind === 'set')) { operators.push(node.kind); } if (typeof node.async === 'boolean' && node.async) { operators.push('async'); } if (typeof node.static === 'boolean' && node.static) { operators.push('static'); } if (typeof node.generator === 'boolean' && node.generator) { operators.push('function*'); } // Calculate method declaration name if (typeof node.computed === 'boolean' && node.computed) { name = node.key.type === 'StringLiteral' ? _TraitUtil2.default.safeValue(node.key) : '<computed~' + _ASTGenerator2.default.parse(node.key).source + '>'; operands.push.apply(operands, (0, _toConsumableArray3.default)(s_SAFE_COMPUTED_OPERANDS(node, parent))); operators.push.apply(operators, (0, _toConsumableArray3.default)(_ASTGenerator2.default.parse(node.key).operators)); } else // ClassMethod is not computed and is an `Identifier` node. { name = _TraitUtil2.default.safeName(node.key); operands.push(name); } var paramNames = []; // Parse params; must use ASTGenerator if (Array.isArray(node.params)) { node.params.forEach(function (param) { var parsedParams = _ASTGenerator2.default.parse(param); operands.push.apply(operands, (0, _toConsumableArray3.default)(parsedParams.operands)); operators.push.apply(operators, (0, _toConsumableArray3.default)(parsedParams.operators)); // For param names only the left hand node of AssignmentPattern must be considered. if (param.type === 'AssignmentPattern') { paramNames.push.apply(paramNames, (0, _toConsumableArray3.default)(_ASTGenerator2.default.parse(param.left).operands)); } else { paramNames.push.apply(paramNames, (0, _toConsumableArray3.default)(parsedParams.operands)); } }); } return { type: 'method', name: name, cyclomatic: 1, lineStart: node.loc.start.line, lineEnd: node.loc.end.line, lloc: 1, operands: new _HalsteadArray2.default('operands', operands), operators: new _HalsteadArray2.default('operators', operators), paramNames: paramNames }; }); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#decorator * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'Decorator', value: function Decorator() { return (0, _actualize2.default)(0, 0); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#directive * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'Directive', value: function Directive() { return (0, _actualize2.default)(1, 0); } /** * Avoid conflicts between string literals and identifiers. * * @see https://github.com/babel/babylon/blob/master/ast/spec.md#directiveliteral * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'DirectiveLiteral', value: function DirectiveLiteral() { return (0, _actualize2.default)(0, 0, void 0, function (node) { return typeof node.value === 'string' ? '"' + node.value + '"' : node.value; }); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#nullliteral * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'NullLiteral', value: function NullLiteral() { return (0, _actualize2.default)(0, 0, void 0, 'null'); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#numericliteral * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'NumericLiteral', value: function NumericLiteral() { return (0, _actualize2.default)(0, 0, void 0, function (node) { return node.value; }); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#objectmethod * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'ObjectMethod', value: function ObjectMethod() { return (0, _actualize2.default)(1, 0, function (node) { return typeof node.kind === 'string' && (node.kind === 'get' || node.kind === 'set') ? node.kind : void 0; }, void 0, 'key'); // Note: must skip key as the assigned name is forwarded on to FunctionExpression. } /** * Note: that w/ ES6+ `:` may be omitted and the Property node defines `shorthand` to indicate this case. * * @see https://github.com/babel/babylon/blob/master/ast/spec.md#objectproperty * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'ObjectProperty', value: function ObjectProperty() { return (0, _actualize2.default)(1, 0, function (node) { return typeof node.shorthand === 'undefined' ? ':' : typeof node.shorthand === 'boolean' && !node.shorthand ? ':' : void 0; }); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#regexpliteral * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'RegExpLiteral', value: function RegExpLiteral() { return (0, _actualize2.default)(0, 0, void 0, function (node) { var operands = []; if ((0, _typeof3.default)(node.extra) === 'object' && typeof node.extra.raw !== 'undefined') { operands.push(node.extra.raw); } return operands; }); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#restproperty * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'RestProperty', value: function RestProperty() { return (0, _actualize2.default)(0, 0, '... (rest)'); } /** * @see https://github.com/babel/babylon/blob/master/ast/spec.md#spreadproperty * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'SpreadProperty', value: function SpreadProperty() { return (0, _actualize2.default)(0, 0, '... (spread)'); } /** * Avoid conflicts between string literals and identifiers. * * @see https://github.com/babel/babylon/blob/master/ast/spec.md#stringliteral * @returns {{lloc: *, cyclomatic: *, operators: *, operands: *, ignoreKeys: *, newScope: *, dependencies: *}} */ }, { key: 'StringLiteral', value: function StringLiteral() { return (0, _actualize2.default)(0, 0, void 0, function (node) { return '"' + node.value + '"'; }); } }]); return PluginSyntaxBabylon; }(_PluginSyntaxESTree3.default); /** * Provides a utility method that determines the operands of a method for Babylon AST nodes. If the name is a computed * value and not a string literal then `ASTGenerator` is invoked to determine the computed operands. * * @param {object} node - The current AST node. * * @returns {Array<*>} */ exports.default = PluginSyntaxBabylon; function s_SAFE_COMPUTED_OPERANDS(node) { var operands = []; if (typeof node.computed === 'boolean' && node.computed) { // The following will pick up a single literal computed value (string). if (node.key.type === 'StringLiteral') { operands.push(_TraitUtil2.default.safeValue(node.key)); } else // Fully evaluate AST node and children for computed operands. { operands.push.apply(operands, (0, _toConsumableArray3.default)(_ASTGenerator2.default.parse(node.key).operands)); } } else // Parent is not computed and `parent.key` is an `Identifier` node. { operands.push(_TraitUtil2.default.safeName(node.key)); } return operands; } module.exports = exports['default'];