babel-plugin-yui3
Version:
Babel plugin for YUI3
247 lines (197 loc) • 7.02 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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; }; }(); /* eslint max-len: 0 */
var _babelTraverse = require('babel-traverse');
var _babelTypes = require('babel-types');
var t = _interopRequireWildcard(_babelTypes);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var findSuperCalls = {
Super: function Super(path) {
if (path.parentPath.isMemberExpression()) {
this.push(path.parentPath);
}
}
};
var ClassTransformer = function () {
function ClassTransformer(path) {
_classCallCheck(this, ClassTransformer);
path = path || _babelTraverse.NodePath;
var _path = path,
scope = _path.scope,
node = _path.node;
this.body = [];
this.node = node;
this.path = path;
this.scope = scope;
this.classRef = node.id ? t.identifier(node.id.name) : this.scope.generateUidIdentifier('class');
this.superName = node.superClass || t.identifier('Y.Base');
this.hasSuper = !!node.superClass;
}
_createClass(ClassTransformer, [{
key: 'build',
value: function build() {
var closureArgs = [];
var closureParams = [];
var body = this.body,
hasSuper = this.hasSuper,
scope = this.scope;
var superName = this.superName;
if (hasSuper) {
closureArgs.push(superName);
superName = scope.generateUidIdentifierBasedOnNode(superName);
closureParams.push(superName);
this.superName = superName;
}
var classBody = this.buildClass();
body.push(classBody);
var container = t.functionExpression(null, closureParams, t.blockStatement(body));
return t.callExpression(container, closureArgs);
}
}, {
key: 'buildClass',
value: function buildClass() {
var className = this.getName();
var baseCreate = t.callExpression(t.identifier('Y.Base.create'), [t.stringLiteral(className), this.superName, this.buildAugments(), this.buildMethods(), this.buildAttrs()]);
return t.returnStatement(baseCreate);
}
}, {
key: 'buildMethods',
value: function buildMethods() {
var _this = this;
var methods = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.path.get('body.body')[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var path = _step.value;
var node = path.node;
if (t.isClassMethod(node)) {
var superClassMethodCalls = [];
path.traverse(findSuperCalls, superClassMethodCalls);
superClassMethodCalls.forEach(function (superPath) {
return _this.replaceSuperCall(superPath);
});
methods.push(t.objectMethod('method', node.key, node.params, node.body));
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return t.objectExpression(methods);
}
}, {
key: 'buildAugments',
value: function buildAugments() {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = this.path.get('body.body')[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var path = _step2.value;
var node = path.node;
if (t.isClassProperty(node) && node.key.name === 'AUGMENTS') {
return node.value;
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return t.arrayExpression([]);
}
}, {
key: 'buildAttrs',
value: function buildAttrs() {
var statics = [];
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = this.path.get('body.body')[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var path = _step3.value;
var node = path.node;
if (t.isClassProperty(node) && node.key.name !== 'AUGMENTS') {
statics.push(t.objectProperty(node.key, node.value));
}
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
return t.objectExpression(statics);
}
}, {
key: 'hasModuleName',
value: function hasModuleName() {
return this.getModuleName() !== null;
}
}, {
key: 'getModuleName',
value: function getModuleName() {
if (!this.node.decorators) {
return null;
}
var moduleNameExpression = this.node.decorators.filter(function (decorator) {
return t.isCallExpression(decorator.expression);
}).map(function (decorator) {
return decorator.expression;
}).find(function (expression) {
return expression.callee.name === 'moduleName';
});
if (moduleNameExpression.arguments.length > 0) {
return moduleNameExpression.arguments[0].value;
}
return null;
}
}, {
key: 'getName',
value: function getName() {
return this.classRef.name;
}
}, {
key: 'replaceSuperCall',
value: function replaceSuperCall(superPath) {
var methodName = superPath.container.callee.property.name;
var applyMethod = t.identifier(this.getName() + '.superclass.' + methodName + '.apply');
var args = superPath.container.arguments;
superPath.parentPath.replaceWith(t.callExpression(applyMethod, [t.identifier('this'), t.arrayExpression(args)]));
}
}]);
return ClassTransformer;
}();
exports.default = ClassTransformer;