UNPKG

metal-soy-critic

Version:
119 lines (118 loc) 4.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const babylon = require("babylon"); const T = require("babel-types"); const babel_traverse_1 = require("babel-traverse"); class JSContext { constructor(raw) { this.raw = raw; this.ast = babylon.parse(raw, { allowImportExportEverywhere: true }); this._defaultBinding = this._getDefaultBinding(); } static getNameOrMemberName(node) { if (T.isIdentifier(node)) { return node.name; } else if (T.isMemberExpression(node)) { return JSContext.getKeyName(node.property); } return null; } static getKeyName(node) { if (T.isIdentifier(node)) { return node.name; } else if (T.isStringLiteral(node)) { return node.value; } throw new Error('Unable to parse key name'); } static hasAttribute(node, name) { if (T.isIdentifier(node) && node.name === 'Config') { return false; } if (T.isCallExpression(node) && T.isMemberExpression(node.callee) && T.isIdentifier(node.callee.property)) { if (node.callee.property.name === name) { return true; } return JSContext.hasAttribute(node.callee.object, name); } return false; } getClassMethodNames() { const methodNames = []; if (this._defaultBinding && T.isClassDeclaration(this._defaultBinding.path.node)) { this._defaultBinding.path.node.body.body.forEach(node => { if (T.isClassMethod(node)) { methodNames.push(JSContext.getKeyName(node.key)); } }); } return methodNames; } getParentClassName() { if (this._defaultBinding && T.isClassDeclaration(this._defaultBinding.path.node)) { return JSContext.getNameOrMemberName(this._defaultBinding.path.node.superClass); } return null; } getParams() { let params = []; if (this._defaultBinding) { for (let i = 0; i < this._defaultBinding.referencePaths.length; i++) { const { parentPath } = this._defaultBinding.referencePaths[i]; if (T.isMemberExpression(parentPath.node) && T.isIdentifier(parentPath.node.property) && parentPath.node.property.name === 'STATE' && T.isAssignmentExpression(parentPath.parentPath.node) && T.isObjectExpression(parentPath.parentPath.node.right)) { params = parentPath.parentPath.node.right.properties .filter(node => T.isObjectProperty(node)); break; } } } return params; } getParamNames() { return this.getParams() .map(param => JSContext.getKeyName(param.key)); } getSuperClassImportPath() { let importPath = null; const parentClassName = this.getParentClassName(); if (parentClassName) { this.visit({ Program(path) { const binding = path.scope.getBinding(parentClassName); if (binding && T.isImportDeclaration(binding.path.parentPath.node)) { importPath = binding.path.parentPath.node.source.value; path.stop(); } } }); } return importPath; } visit(traverseOptions) { babel_traverse_1.default(this.ast, traverseOptions); } _getDefaultBinding() { let binding = null; this.visit({ ExportDefaultDeclaration(path) { path.stop(); if (T.isIdentifier(path.node.declaration)) { binding = path .findParent(path => path.isProgram()) .scope .getBinding(path.node.declaration.name); } } }); return binding; } } exports.default = JSContext;