canonical
Version:
Canonical code style linter and formatter for JavaScript, SCSS and CSS.
245 lines (196 loc) • 18.6 kB
JavaScript
'use strict';
var _createClass = require('babel-runtime/helpers/create-class')['default'];
var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];
var _Map = require('babel-runtime/core-js/map')['default'];
var _Set = require('babel-runtime/core-js/set')['default'];
var _interopRequireWildcard = require('babel-runtime/helpers/interop-require-wildcard')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.recursivePatternCapture = recursivePatternCapture;
var _fs = require('fs');
var fs = _interopRequireWildcard(_fs);
var _crypto = require('crypto');
var _parse2 = require('./parse');
var _parse3 = _interopRequireDefault(_parse2);
var _resolve = require('./resolve');
var _resolve2 = _interopRequireDefault(_resolve);
var _ignore = require('./ignore');
var _ignore2 = _interopRequireDefault(_ignore);
// map from settings sha1 => path => export map objects
var exportCaches = new _Map();
var ExportMap = (function () {
function ExportMap(context) {
_classCallCheck(this, ExportMap);
this.context = context;
this.named = new _Set();
this.errors = [];
}
/**
* Traverse a patter/identifier node, calling 'callback'
* for each leaf identifier.
* @param {node} pattern
* @param {Function} callback
* @return {void}
*/
_createClass(ExportMap, [{
key: 'resolveReExport',
value: function resolveReExport(node, base) {
var remotePath = _resolve2['default'].relative(node.source.value, base, this.settings);
if (remotePath == null) return null;
return ExportMap['for'](remotePath, this.context);
}
}, {
key: 'captureDefault',
value: function captureDefault(n) {
if (n.type !== 'ExportDefaultDeclaration') return;
this.named.add('default');
}
/**
* capture all named exports from remote module.
*
* returns null if this node wasn't an ExportAllDeclaration
* returns false if it was not resolved
* returns true if it was resolved + parsed
*
* @param {node} n
* @param {string} path - the path of the module currently parsing
* @return {boolean?}
*/
}, {
key: 'captureAll',
value: function captureAll(n, path) {
if (n.type !== 'ExportAllDeclaration') return null;
var remoteMap = this.resolveReExport(n, path);
if (remoteMap == null) return false;
remoteMap.named.forEach((function (name) {
this.named.add(name);
}).bind(this));
return true;
}
}, {
key: 'captureNamedDeclaration',
value: function captureNamedDeclaration(n, path) {
var _this = this;
if (n.type !== 'ExportNamedDeclaration') return;
// capture declaration
if (n.declaration != null) {
switch (n.declaration.type) {
case 'FunctionDeclaration':
case 'ClassDeclaration':
this.named.add(n.declaration.id.name);
break;
case 'VariableDeclaration':
n.declaration.declarations.forEach(function (d) {
return recursivePatternCapture(d.id, function (id) {
return _this.named.add(id.name);
});
});
break;
}
}
// capture specifiers
var remoteMap = undefined;
if (n.source) remoteMap = this.resolveReExport(n, path);
n.specifiers.forEach((function (s) {
if (s.type === 'ExportDefaultSpecifier') {
// don't add it if it is not present in the exported module
if (!remoteMap || !remoteMap.hasDefault) return;
}
this.named.add(s.exported.name);
}).bind(this));
}
}, {
key: 'settings',
get: function get() {
return this.context && this.context.settings;
}
}, {
key: 'hasDefault',
get: function get() {
return this.named.has('default');
}
}, {
key: 'hasNamed',
get: function get() {
return this.named.size > (this.hasDefault ? 1 : 0);
}
}], [{
key: 'get',
value: function get(source, context) {
var path = (0, _resolve2['default'])(source, context);
if (path == null || (0, _ignore2['default'])(path, context)) return null;
return ExportMap['for'](path, context);
}
}, {
key: 'for',
value: function _for(path, context) {
var exportMap = undefined;
var stats = fs.statSync(path);
var cacheKey = hashObject(context.settings);
var exportCache = exportCaches.get(cacheKey);
if (exportCache === undefined) {
exportCache = new _Map();
exportCaches.set(cacheKey, exportCache);
}
exportMap = exportCache.get(path);
if (exportMap != null) {
// date equality check
if (exportMap.mtime - stats.mtime === 0) {
return exportMap;
}
// future: check content equality?
}
exportMap = ExportMap.parse(path, context);
exportCache.set(path, exportMap);
exportMap.mtime = stats.mtime;
return exportMap;
}
}, {
key: 'parse',
value: function parse(path, context) {
var m = new ExportMap(context);
try {
var ast = (0, _parse3['default'])(path, context);
} catch (err) {
m.errors.push(err);
return m; // can't continue
}
ast.body.forEach(function (n) {
m.captureDefault(n);
m.captureAll(n, path);
m.captureNamedDeclaration(n, path);
});
return m;
}
}]);
return ExportMap;
})();
exports['default'] = ExportMap;
function recursivePatternCapture(pattern, callback) {
switch (pattern.type) {
case 'Identifier':
// base case
callback(pattern);
break;
case 'ObjectPattern':
pattern.properties.forEach(function (_ref) {
var value = _ref.value;
recursivePatternCapture(value, callback);
});
break;
case 'ArrayPattern':
pattern.elements.forEach(function (element) {
if (element == null) return;
recursivePatternCapture(element, callback);
});
break;
}
}
function hashObject(object) {
var settingsShasum = (0, _crypto.createHash)('sha1');
settingsShasum.update(JSON.stringify(object));
return settingsShasum.digest('hex');
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL2dldEV4cG9ydHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztrQkFBb0IsSUFBSTs7SUFBWixFQUFFOztzQkFFYSxRQUFROztzQkFFakIsU0FBUzs7Ozt1QkFDUCxXQUFXOzs7O3NCQUNULFVBQVU7Ozs7O0FBR2hDLElBQU0sWUFBWSxHQUFHLFVBQVMsQ0FBQTs7SUFFVCxTQUFTO0FBQ2pCLFdBRFEsU0FBUyxDQUNoQixPQUFPLEVBQUU7MEJBREYsU0FBUzs7QUFFMUIsUUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUE7QUFDdEIsUUFBSSxDQUFDLEtBQUssR0FBRyxVQUFTLENBQUE7O0FBRXRCLFFBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFBO0dBQ2pCOzs7Ozs7Ozs7O2VBTmtCLFNBQVM7O1dBb0ViLHlCQUFDLElBQUksRUFBRSxJQUFJLEVBQUU7QUFDMUIsVUFBSSxVQUFVLEdBQUcscUJBQVEsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7QUFDekUsVUFBSSxVQUFVLElBQUksSUFBSSxFQUFFLE9BQU8sSUFBSSxDQUFBOztBQUVuQyxhQUFPLFNBQVMsT0FBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7S0FDL0M7OztXQUVhLHdCQUFDLENBQUMsRUFBRTtBQUNoQixVQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssMEJBQTBCLEVBQUUsT0FBTTtBQUNqRCxVQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtLQUMxQjs7Ozs7Ozs7Ozs7Ozs7O1dBYVMsb0JBQUMsQ0FBQyxFQUFFLElBQUksRUFBRTtBQUNsQixVQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssc0JBQXNCLEVBQUUsT0FBTyxJQUFJLENBQUE7O0FBRWxELFVBQUksU0FBUyxHQUFH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dHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcydcblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0bydcblxuaW1wb3J0IHBhcnNlIGZyb20gJy4vcGFyc2UnXG5pbXBvcnQgcmVzb2x2ZSBmcm9tICcuL3Jlc29sdmUnXG5pbXBvcnQgaXNJZ25vcmVkIGZyb20gJy4vaWdub3JlJ1xuXG4vLyBtYXAgZnJvbSBzZXR0aW5ncyBzaGExID0+IHBhdGggPT4gZXhwb3J0IG1hcCBvYmplY3RzXG5jb25zdCBleHBvcnRDYWNoZXMgPSBuZXcgTWFwKClcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhwb3J0TWFwIHtcbiAgY29uc3RydWN0b3IoY29udGV4dCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgICB0aGlzLm5hbWVkID0gbmV3IFNldCgpXG5cbiAgICB0aGlzLmVycm9ycyA9IFtdXG4gIH1cblxuICBnZXQgc2V0dGluZ3MoKSB7IHJldHVybiB0aGlzLmNvbnRleHQgJiYgdGhpcy5jb250ZXh0LnNldHRpbmdzIH1cblxuICBnZXQgaGFzRGVmYXVsdCgpIHsgcmV0dXJuIHRoaXMubmFtZWQuaGFzKCdkZWZhdWx0JykgfVxuICBnZXQgaGFzTmFtZWQoKSB7IHJldHVybiB0aGlzLm5hbWVkLnNpemUgPiAodGhpcy5oYXNEZWZhdWx0ID8gMSA6IDApIH1cblxuICBzdGF0aWMgZ2V0KHNvdXJjZSwgY29udGV4dCkge1xuXG4gICAgdmFyIHBhdGggPSByZXNvbHZlKHNvdXJjZSwgY29udGV4dClcbiAgICBpZiAocGF0aCA9PSBudWxsIHx8IGlzSWdub3JlZChwYXRoLCBjb250ZXh0KSkgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiBFeHBvcnRNYXAuZm9yKHBhdGgsIGNvbnRleHQpXG4gIH1cblxuICBzdGF0aWMgZm9yKHBhdGgsIGNvbnRleHQpIHtcbiAgICBsZXQgZXhwb3J0TWFwXG4gICAgY29uc3Qgc3RhdHMgPSBmcy5zdGF0U3luYyhwYXRoKVxuXG4gICAgY29uc3QgY2FjaGVLZXkgPSBoYXNoT2JqZWN0KGNvbnRleHQuc2V0dGluZ3MpXG4gICAgbGV0IGV4cG9ydENhY2hlID0gZXhwb3J0Q2FjaGVzLmdldChjYWNoZUtleSlcbiAgICBpZiAoZXhwb3J0Q2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZXhwb3J0Q2FjaGUgPSBuZXcgTWFwKClcbiAgICAgIGV4cG9ydENhY2hlcy5zZXQoY2FjaGVLZXksIGV4cG9ydENhY2hlKVxuICAgIH1cblxuICAgIGV4cG9ydE1hcCA9IGV4cG9ydENhY2hlLmdldChwYXRoKVxuICAgIGlmIChleHBvcnRNYXAgIT0gbnVsbCkge1xuICAgICAgLy8gZGF0ZSBlcXVhbGl0eSBjaGVja1xuICAgICAgaWYgKGV4cG9ydE1hcC5tdGltZSAtIHN0YXRzLm10aW1lID09PSAwKSB7XG4gICAgICAgIHJldHVybiBleHBvcnRNYXBcbiAgICAgIH1cbiAgICAgIC8vIGZ1dHVyZTogY2hlY2sgY29udGVudCBlcXVhbGl0eT9cbiAgICB9XG5cbiAgICBleHBvcnRNYXAgPSBFeHBvcnRNYXAucGFyc2UocGF0aCwgY29udGV4dClcblxuICAgIGV4cG9ydENhY2hlLnNldChwYXRoLCBleHBvcnRNYXApXG4gICAgZXhwb3J0TWFwLm10aW1lID0gc3RhdHMubXRpbWVcblxuICAgIHJldHVybiBleHBvcnRNYXBcbiAgfVxuXG4gIHN0YXRpYyBwYXJzZShwYXRoLCBjb250ZXh0KSB7XG4gICAgdmFyIG0gPSBuZXcgRXhwb3J0TWFwKGNvbnRleHQpXG5cbiAgICB0cnkge1xuICAgICAgdmFyIGFzdCA9IHBhcnNlKHBhdGgsIGNvbnRleHQpXG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBtLmVycm9ycy5wdXNoKGVycilcbiAgICAgIHJldHVybiBtIC8vIGNhbid0IGNvbnRpbnVlXG4gICAgfVxuXG4gICAgYXN0LmJvZHkuZm9yRWFjaChmdW5jdGlvbiAobikge1xuICAgICAgbS5jYXB0dXJlRGVmYXVsdChuKVxuICAgICAgbS5jYXB0dXJlQWxsKG4sIHBhdGgpXG4gICAgICBtLmNhcHR1cmVOYW1lZERlY2xhcmF0aW9uKG4sIHBhdGgpXG4gICAgfSlcblxuICAgIHJldHVybiBtXG4gIH1cblxuICByZXNvbHZlUmVFeHBvcnQobm9kZSwgYmFzZSkge1xuICAgIHZhciByZW1vdGVQYXRoID0gcmVzb2x2ZS5yZWxhdGl2ZShub2RlLnNvdXJjZS52YWx1ZSwgYmFzZSwgdGhpcy5zZXR0aW5ncylcbiAgICBpZiAocmVtb3RlUGF0aCA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gICAgcmV0dXJuIEV4cG9ydE1hcC5mb3IocmVtb3RlUGF0aCwgdGhpcy5jb250ZXh0KVxuICB9XG5cbiAgY2FwdHVyZURlZmF1bHQobikge1xuICAgIGlmIChuLnR5cGUgIT09ICdFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24nKSByZXR1cm5cbiAgICB0aGlzLm5hbWVkLmFkZCgnZGVmYXVsdCcpXG4gIH1cblxuICAvKipcbiAgICogY2FwdHVyZSBhbGwgbmFtZWQgZXhwb3J0cyBmcm9tIHJlbW90ZSBtb2R1bGUuXG4gICAqXG4gICAqIHJldHVybnMgbnVsbCBpZiB0aGlzIG5vZGUgd2Fzbid0IGFuIEV4cG9ydEFsbERlY2xhcmF0aW9uXG4gICAqIHJldHVybnMgZmFsc2UgaWYgaXQgd2FzIG5vdCByZXNvbHZlZFxuICAgKiByZXR1cm5zIHRydWUgaWYgaXQgd2FzIHJlc29sdmVkICsgcGFyc2VkXG4gICAqXG4gICAqIEBwYXJhbSAge25vZGV9IG5cbiAgICogQHBhcmFtICB7c3RyaW5nfSBwYXRoIC0gdGhlIHBhdGggb2YgdGhlIG1vZHVsZSBjdXJyZW50bHkgcGFyc2luZ1xuICAgKiBAcmV0dXJuIHtib29sZWFuP31cbiAgICovXG4gIGNhcHR1cmVBbGwobiwgcGF0aCkge1xuICAgIGlmIChuLnR5cGUgIT09ICdFeHBvcnRBbGxEZWNsYXJhdGlvbicpIHJldHVybiBudWxsXG5cbiAgICB2YXIgcmVtb3RlTWFwID0gdGhpcy5yZXNvbHZlUmVFeHBvcnQobiwgcGF0aClcbiAgICBpZiAocmVtb3RlTWFwID09IG51bGwpIHJldHVybiBmYWxzZVxuXG4gICAgcmVtb3RlTWFwLm5hbWVkLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lZC5hZGQobmFtZSkgfS5iaW5kKHRoaXMpKVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGNhcHR1cmVOYW1lZERlY2xhcmF0aW9uKG4sIHBhdGgpIHtcbiAgICBpZiAobi50eXBlICE9PSAnRXhwb3J0TmFtZWREZWNsYXJhdGlvbicpIHJldHVyblxuXG4gICAgLy8gY2FwdHVyZSBkZWNsYXJhdGlvblxuICAgIGlmIChuLmRlY2xhcmF0aW9uICE9IG51bGwpIHtcbiAgICAgIHN3aXRjaCAobi5kZWNsYXJhdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0Z1bmN0aW9uRGVjbGFyYXRpb24nOlxuICAgICAgICBjYXNlICdDbGFzc0RlY2xhcmF0aW9uJzpcbiAgICAgICAgICB0aGlzLm5hbWVkLmFkZChuLmRlY2xhcmF0aW9uLmlkLm5hbWUpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnVmFyaWFibGVEZWNsYXJhdGlvbic6XG4gICAgICAgICAgbi5kZWNsYXJhdGlvbi5kZWNsYXJhdGlvbnMuZm9yRWFjaCgoZCkgPT5cbiAgICAgICAgICAgIHJlY3Vyc2l2ZVBhdHRlcm5DYXB0dXJlKGQuaWQsIGlkID0+IHRoaXMubmFtZWQuYWRkKGlkLm5hbWUpKSlcbiAgICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNhcHR1cmUgc3BlY2lmaWVyc1xuICAgIGxldCByZW1vdGVNYXBcbiAgICBpZiAobi5zb3VyY2UpIHJlbW90ZU1hcCA9IHRoaXMucmVzb2x2ZVJlRXhwb3J0KG4sIHBhdGgpXG5cbiAgICBuLnNwZWNpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAocykge1xuICAgICAgaWYgKHMudHlwZSA9PT0gJ0V4cG9ydERlZmF1bHRTcGVjaWZpZXInKSB7XG4gICAgICAgIC8vIGRvbid0IGFkZCBpdCBpZiBpdCBpcyBub3QgcHJlc2VudCBpbiB0aGUgZXhwb3J0ZWQgbW9kdWxlXG4gICAgICAgIGlmICghcmVtb3RlTWFwIHx8ICFyZW1vdGVNYXAuaGFzRGVmYXVsdCkgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHRoaXMubmFtZWQuYWRkKHMuZXhwb3J0ZWQubmFtZSlcbiAgICB9LmJpbmQodGhpcykpXG4gIH1cbn1cblxuXG4vKipcbiAqIFRyYXZlcnNlIGEgcGF0dGVyL2lkZW50aWZpZXIgbm9kZSwgY2FsbGluZyAnY2FsbGJhY2snXG4gKiBmb3IgZWFjaCBsZWFmIGlkZW50aWZpZXIuXG4gKiBAcGFyYW0gIHtub2RlfSAgIHBhdHRlcm5cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHJldHVybiB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY3Vyc2l2ZVBhdHRlcm5DYXB0dXJlKHBhdHRlcm4sIGNhbGxiYWNrKSB7XG4gIHN3aXRjaCAocGF0dGVybi50eXBlKSB7XG4gICAgY2FzZSAnSWRlbnRpZmllcic6IC8vIGJhc2UgY2FzZVxuICAgICAgY2FsbGJhY2socGF0dGVybilcbiAgICAgIGJyZWFrXG5cbiAgICBjYXNlICdPYmplY3RQYXR0ZXJuJzpcbiAgICAgIHBhdHRlcm4ucHJvcGVydGllcy5mb3JFYWNoKCh7IHZhbHVlIH0pID0+IHtcbiAgICAgICAgcmVjdXJzaXZlUGF0dGVybkNhcHR1cmUodmFsdWUsIGNhbGxiYWNrKVxuICAgICAgfSlcbiAgICAgIGJyZWFrXG5cbiAgICBjYXNlICdBcnJheVBhdHRlcm4nOlxuICAgICAgcGF0dGVybi5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChlbGVtZW50ID09IG51bGwpIHJldHVyblxuICAgICAgICByZWN1cnNpdmVQYXR0ZXJuQ2FwdHVyZShlbGVtZW50LCBjYWxsYmFjaylcbiAgICAgIH0pXG4gICAgICBicmVha1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhc2hPYmplY3Qob2JqZWN0KSB7XG4gIGNvbnN0IHNldHRpbmdzU2hhc3VtID0gY3JlYXRlSGFzaCgnc2hhMScpXG4gIHNldHRpbmdzU2hhc3VtLnVwZGF0ZShKU09OLnN0cmluZ2lmeShvYmplY3QpKVxuICByZXR1cm4gc2V0dGluZ3NTaGFzdW0uZGlnZXN0KCdoZXgnKVxufVxuIl19