wallet-core/node_modules/babel-plugin-espower/lib/babel-espower-visitor.js
2017-05-28 00:40:43 +02:00

87 lines
3.1 KiB
JavaScript

'use strict';
var CallMatcher = require('call-matcher');
var babylon = require('babylon');
var assign = require('core-js/library/fn/object/assign');
var find = require('core-js/library/fn/array/find');
var BabelAssertionVisitor = require('./babel-assertion-visitor');
function BabelEspowerVisitor (babel, opts) {
this.babel = babel;
this.matchers = opts.patterns.map(function (pattern) {
var signatureAst = babylon.parse(pattern);
var expression = signatureAst.program.body[0].expression;
return new CallMatcher(expression, opts);
});
this.options = opts;
}
BabelEspowerVisitor.prototype.enter = function (nodePath) {
var currentNode = nodePath.node;
var file = nodePath.hub.file;
var assertionVisitor = file.get('espowerAssertionVisitor');
if (assertionVisitor) {
if (assertionVisitor.isGeneratedNode(nodePath) || assertionVisitor.toBeSkipped(nodePath)) {
// skipping this Node
// MEMO: exit() will not be called when skip() is called
nodePath.skip();
return;
}
if (!assertionVisitor.isCapturingArgument() && !this.isCalleeOfParentCallExpression(nodePath)) {
// entering argument
assertionVisitor.enterArgument(nodePath);
}
} else if (nodePath.isCallExpression()) {
var matcher = find(this.matchers, function (m) { return m.test(currentNode); });
if (matcher) {
// entering assertion
var espowerOptions = assign({
path: file.opts.filename, // or opts.sourceFileName?
sourceMap: file.opts.inputSourceMap
}, this.options);
assertionVisitor = new BabelAssertionVisitor(this.babel, matcher, espowerOptions);
assertionVisitor.enter(nodePath);
file.set('espowerAssertionVisitor', assertionVisitor);
}
}
};
BabelEspowerVisitor.prototype.exit = function (nodePath) {
var currentNode = nodePath.node;
var resultTree = currentNode;
var file = nodePath.hub.file;
var assertionVisitor = file.get('espowerAssertionVisitor');
if (!assertionVisitor) {
return;
}
if (assertionVisitor.isLeavingAssertion(nodePath)) {
// leaving assertion
assertionVisitor.leave(nodePath);
file.delete('espowerAssertionVisitor');
return;
}
if (!assertionVisitor.isCapturingArgument()) {
return;
}
if (assertionVisitor.toBeCaptured(nodePath)) {
// capturing Node
resultTree = assertionVisitor.captureNode(nodePath);
}
if (assertionVisitor.isLeavingArgument(nodePath)) {
// capturing whole argument on leaving argument
resultTree = assertionVisitor.leaveArgument(resultTree);
}
if (resultTree !== currentNode) {
nodePath.replaceWith(resultTree);
}
};
BabelEspowerVisitor.prototype.isCalleeOfParentCallExpression = function (nodePath) {
var currentKey = nodePath.key;
var parentNode = nodePath.parent;
var types = this.babel.types;
return types.isCallExpression(parentNode) && currentKey === 'callee';
};
module.exports = BabelEspowerVisitor;