lesslint
Version:
lint your less code
126 lines (98 loc) • 11.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.check = undefined;
var _chalk = require('chalk');
var _chalk2 = _interopRequireDefault(_chalk);
var _postcss = require('postcss');
var _postcss2 = _interopRequireDefault(_postcss);
var _postcssValuesParser = require('postcss-values-parser');
var _postcssValuesParser2 = _interopRequireDefault(_postcssValuesParser);
var _util = require('../util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @file 运算符检验
* + / - 两侧的操作数必须(MUST)有相同的单位,如果其中一个是变量,另一个数值必须(MUST)书写单位。
* https://github.com/ecomfe/spec/blob/master/less-code-style.md#%E8%BF%90%E7%AE%97
* @author ielgnaw(wuji0223@gmail.com)
*/
;
/**
* 规则名称
*
* @const
* @type {string}
*/
var RULENAME = 'operate-unit';
/**
* 错误信息
*
* @const
* @type {string}
*/
var MSG = '' + '`+`、`-` on both sides of the operand must have the same unit, ' + 'if one side has unit, the other side must has unit';
/**
* 具体的检测逻辑
*
* @param {Object} opts 参数
* @param {*} opts.ruleVal 当前规则具体配置的值
* @param {string} opts.fileContent 文件内容
* @param {string} opts.filePath 文件路径
*/
var check = exports.check = _postcss2.default.plugin(RULENAME, function (opts) {
return function (css, result) {
if (!opts.ruleVal) {
return;
}
// TODO:
// `@a: 1 + 2;` is walkDecls
// `@a : 1 + 2;` is walkAtRules 这种情况还未处理
/* jshint maxcomplexity:false */
css.walkDecls(function (decl) {
var valueAst = (0, _postcssValuesParser2.default)(decl.value).parse();
valueAst.walk(function (child) {
if (child.type !== 'operator' || child.value !== '+' && child.value !== '-') {
return;
}
var parent = child.parent;
// 当前 child 的索引
var index = parent.index(child);
// child 的后一个元素
var nextElem = parent.nodes[index + 1];
// child 的前一个元素
var prevElem = parent.nodes[index - 1] || {};
var problemElem = null;
// 后一个是变量
if (nextElem.type === 'atword' && prevElem.type !== 'atword') {
if (!prevElem.unit) {
problemElem = prevElem;
}
}
// 前一个是变量
if (prevElem.type === 'atword' && nextElem.type !== 'atword') {
if (!nextElem.unit) {
problemElem = nextElem;
}
}
if (problemElem) {
var source = decl.source,
prop = decl.prop,
raws = decl.raws;
var line = source.start.line;
var lineContent = (0, _util.getLineContent)(line, source.input.css, true);
var col = source.start.column + prop.length + raws.between.length + problemElem.source.start.column - 1;
result.warn(RULENAME, {
node: decl,
ruleName: RULENAME,
line: line,
col: col,
message: '`' + lineContent + '` ' + MSG,
colorMessage: '`' + (0, _util.changeColorByStartAndEndIndex)(lineContent, col, col + problemElem.value.length) + '` ' + _chalk2.default.grey(MSG)
});
}
});
});
};
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlL29wZXJhdGUtdW5pdC5qcyJdLCJuYW1lcyI6WyJSVUxFTkFNRSIsIk1TRyIsImNoZWNrIiwicG9zdGNzcyIsInBsdWdpbiIsImNzcyIsInJlc3VsdCIsIm9wdHMiLCJydWxlVmFsIiwid2Fsa0RlY2xzIiwidmFsdWVBc3QiLCJkZWNsIiwidmFsdWUiLCJwYXJzZSIsIndhbGsiLCJjaGlsZCIsInR5cGUiLCJwYXJlbnQiLCJpbmRleCIsIm5leHRFbGVtIiwibm9kZXMiLCJwcmV2RWxlbSIsInByb2JsZW1FbGVtIiwidW5pdCIsInNvdXJjZSIsInByb3AiLCJyYXdzIiwibGluZSIsInN0YXJ0IiwibGluZUNvbnRlbnQiLCJpbnB1dCIsImNvbCIsImNvbHVtbiIsImxlbmd0aCIsImJldHdlZW4iLCJ3YXJuIiwibm9kZSIsInJ1bGVOYW1lIiwibWVzc2FnZSIsImNvbG9yTWVzc2FnZSIsImNoYWxrIiwiZ3JleSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQU9BOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUVBOzs7O0FBWEE7Ozs7Ozs7QUFhQTs7QUFFQTs7Ozs7O0FBTUEsSUFBTUEsV0FBVyxjQUFqQjs7QUFFQTs7Ozs7O0FBTUEsSUFBTUMsTUFBTSxLQUNOLGdFQURNLEdBRU4sb0RBRk47O0FBSUE7Ozs7Ozs7O0FBUU8sSUFBTUMsd0JBQVFDLGtCQUFRQyxNQUFSLENBQWVKLFFBQWYsRUFBeUI7QUFBQSxXQUMxQyxVQUFDSyxHQUFELEVBQU1DLE1BQU4sRUFBaUI7QUFDYixZQUFJLENBQUNDLEtBQUtDLE9BQVYsRUFBbUI7QUFDZjtBQUNIOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBSCxZQUFJSSxTQUFKLENBQWMsZ0JBQVE7QUFDbEIsZ0JBQU1DLFdBQVcsbUNBQU9DLEtBQUtDLEtBQVosRUFBbUJDLEtBQW5CLEVBQWpCOztBQUVBSCxxQkFBU0ksSUFBVCxDQUFjLGlCQUFTO0FBQ25CLG9CQUFJQyxNQUFNQyxJQUFOLEtBQWUsVUFBZixJQUE4QkQsTUFBTUgsS0FBTixLQUFnQixHQUFoQixJQUF1QkcsTUFBTUgsS0FBTixLQUFnQixHQUF6RSxFQUErRTtBQUMzRTtBQUNIOztBQUhrQixvQkFLWkssTUFMWSxHQUtGRixLQUxFLENBS1pFLE1BTFk7O0FBT25COztBQUNBLG9CQUFNQyxRQUFRRCxPQUFPQyxLQUFQLENBQWFILEtBQWIsQ0FBZDs7QUFFQTtBQUNBLG9CQUFNSSxXQUFXRixPQUFPRyxLQUFQLENBQWFGLFFBQVEsQ0FBckIsQ0FBakI7O0FBRUE7QUFDQSxvQkFBTUcsV0FBV0osT0FBT0csS0FBUCxDQUFhRixRQUFRLENBQXJCLEtBQTJCLEVBQTVDOztBQUVBLG9CQUFJSSxjQUFjLElBQWxCOztBQUVBO0FBQ0Esb0JBQUlILFNBQVNILElBQVQsS0FBa0IsUUFBbEIsSUFBOEJLLFNBQVNMLElBQVQsS0FBa0IsUUFBcEQsRUFBOEQ7QUFDMUQsd0JBQUksQ0FBQ0ssU0FBU0UsSUFBZCxFQUFvQjtBQUNoQkQsc0NBQWNELFFBQWQ7QUFDSDtBQUNKOztBQUVEO0FBQ0Esb0JBQUlBLFNBQVNMLElBQVQsS0FBa0IsUUFBbEIsSUFBOEJHLFNBQVNILElBQVQsS0FBa0IsUUFBcEQsRUFBOEQ7QUFDMUQsd0JBQUksQ0FBQ0csU0FBU0ksSUFBZCxFQUFvQjtBQUNoQkQsc0NBQWNILFFBQWQ7QUFDSDtBQUNKOztBQUVELG9CQUFJRyxXQUFKLEVBQWlCO0FBQUEsd0JBQ05FLE1BRE0sR0FDZ0JiLElBRGhCLENBQ05hLE1BRE07QUFBQSx3QkFDRUMsSUFERixHQUNnQmQsSUFEaEIsQ0FDRWMsSUFERjtBQUFBLHdCQUNRQyxJQURSLEdBQ2dCZixJQURoQixDQUNRZSxJQURSOztBQUViLHdCQUFNQyxPQUFPSCxPQUFPSSxLQUFQLENBQWFELElBQTFCO0FBQ0Esd0JBQU1FLGNBQWMsMEJBQWVGLElBQWYsRUFBcUJILE9BQU9NLEtBQVAsQ0FBYXpCLEdBQWxDLEVBQXVDLElBQXZDLENBQXBCO0FBQ0Esd0JBQU0wQixNQUNBUCxPQUFPSSxLQUFQLENBQWFJLE1BQWIsR0FBc0JQLEtBQUtRLE1BQTNCLEdBQW9DUCxLQUFLUSxPQUFMLENBQWFELE1BQWpELEdBQTBEWCxZQUFZRSxNQUFaLENBQW1CSSxLQUFuQixDQUF5QkksTUFBbkYsR0FBNEYsQ0FEbEc7O0FBR0ExQiwyQkFBTzZCLElBQVAsQ0FBWW5DLFFBQVosRUFBc0I7QUFDbEJvQyw4QkFBTXpCLElBRFk7QUFFbEIwQixrQ0FBVXJDLFFBRlE7QUFHbEIyQiw4QkFBTUEsSUFIWTtBQUlsQkksNkJBQUtBLEdBSmE7QUFLbEJPLGlDQUFTLE1BQU1ULFdBQU4sR0FBb0IsSUFBcEIsR0FBMkI1QixHQUxsQjtBQU1sQnNDLHNDQUFjLE1BQ1IseUNBQThCVixXQUE5QixFQUEyQ0UsR0FBM0MsRUFBZ0RBLE1BQU1ULFlBQVlWLEtBQVosQ0FBa0JxQixNQUF4RSxDQURRLEdBRVIsSUFGUSxHQUdSTyxnQkFBTUMsSUFBTixDQUFXeEMsR0FBWDtBQVRZLHFCQUF0QjtBQVdIO0FBQ0osYUFuREQ7QUFvREgsU0F2REQ7QUF3REgsS0FuRXlDO0FBQUEsQ0FBekIsQ0FBZCIsImZpbGUiOiJvcGVyYXRlLXVuaXQuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlIOi/kOeul+espuajgOmqjFxuICogICAgICAgKyAvIC0g5Lik5L6n55qE5pON5L2c5pWw5b+F6aG777yITVVTVO+8ieacieebuOWQjOeahOWNleS9je+8jOWmguaenOWFtuS4reS4gOS4quaYr+WPmOmHj++8jOWPpuS4gOS4quaVsOWAvOW/hemhu++8iE1VU1TvvInkuablhpnljZXkvY3jgIJcbiAqICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9lY29tZmUvc3BlYy9ibG9iL21hc3Rlci9sZXNzLWNvZGUtc3R5bGUubWQjJUU4JUJGJTkwJUU3JUFFJTk3XG4gKiBAYXV0aG9yIGllbGduYXcod3VqaTAyMjNAZ21haWwuY29tKVxuICovXG5cbmltcG9ydCBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgcG9zdGNzcyBmcm9tICdwb3N0Y3NzJztcbmltcG9ydCBwYXJzZXIgZnJvbSAncG9zdGNzcy12YWx1ZXMtcGFyc2VyJztcblxuaW1wb3J0IHtnZXRMaW5lQ29udGVudCwgY2hhbmdlQ29sb3JCeVN0YXJ0QW5kRW5kSW5kZXh9IGZyb20gJy4uL3V0aWwnO1xuXG4ndXNlIHN0cmljdCc7XG5cbi8qKlxuICog6KeE5YiZ5ZCN56ewXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5jb25zdCBSVUxFTkFNRSA9ICdvcGVyYXRlLXVuaXQnO1xuXG4vKipcbiAqIOmUmeivr+S/oeaBr1xuICpcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuY29uc3QgTVNHID0gJydcbiAgICArICdgK2DjgIFgLWAgb24gYm90aCBzaWRlcyBvZiB0aGUgb3BlcmFuZCBtdXN0IGhhdmUgdGhlIHNhbWUgdW5pdCwgJ1xuICAgICsgJ2lmIG9uZSBzaWRlIGhhcyB1bml0LCB0aGUgb3RoZXIgc2lkZSBtdXN0IGhhcyB1bml0JztcblxuLyoqXG4gKiDlhbfkvZPnmoTmo4DmtYvpgLvovpFcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyDlj4LmlbBcbiAqIEBwYXJhbSB7Kn0gb3B0cy5ydWxlVmFsIOW9k+WJjeinhOWImeWFt+S9k+mFjee9rueahOWAvFxuICogQHBhcmFtIHtzdHJpbmd9IG9wdHMuZmlsZUNvbnRlbnQg5paH5Lu25YaF5a65XG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0cy5maWxlUGF0aCDmlofku7bot6/lvoRcbiAqL1xuZXhwb3J0IGNvbnN0IGNoZWNrID0gcG9zdGNzcy5wbHVnaW4oUlVMRU5BTUUsIG9wdHMgPT5cbiAgICAoY3NzLCByZXN1bHQpID0+IHtcbiAgICAgICAgaWYgKCFvcHRzLnJ1bGVWYWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRPRE86XG4gICAgICAgIC8vIGBAYTogMSArIDI7YCBpcyB3YWxrRGVjbHNcbiAgICAgICAgLy8gYEBhIDogMSArIDI7YCBpcyB3YWxrQXRSdWxlcyDov5nnp43mg4XlhrXov5jmnKrlpITnkIZcblxuICAgICAgICAvKiBqc2hpbnQgbWF4Y29tcGxleGl0eTpmYWxzZSAqL1xuICAgICAgICBjc3Mud2Fsa0RlY2xzKGRlY2wgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmFsdWVBc3QgPSBwYXJzZXIoZGVjbC52YWx1ZSkucGFyc2UoKTtcblxuICAgICAgICAgICAgdmFsdWVBc3Qud2FsayhjaGlsZCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkLnR5cGUgIT09ICdvcGVyYXRvcicgfHwgKGNoaWxkLnZhbHVlICE9PSAnKycgJiYgY2hpbGQudmFsdWUgIT09ICctJykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHtwYXJlbnR9ID0gY2hpbGQ7XG5cbiAgICAgICAgICAgICAgICAvLyDlvZPliY0gY2hpbGQg55qE57Si5byVXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBwYXJlbnQuaW5kZXgoY2hpbGQpO1xuXG4gICAgICAgICAgICAgICAgLy8gY2hpbGQg55qE5ZCO5LiA5Liq5YWD57SgXG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dEVsZW0gPSBwYXJlbnQubm9kZXNbaW5kZXggKyAxXTtcblxuICAgICAgICAgICAgICAgIC8vIGNoaWxkIOeahOWJjeS4gOS4quWFg+e0oFxuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZFbGVtID0gcGFyZW50Lm5vZGVzW2luZGV4IC0gMV0gfHwge307XG5cbiAgICAgICAgICAgICAgICBsZXQgcHJvYmxlbUVsZW0gPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgLy8g5ZCO5LiA5Liq5piv5Y+Y6YePXG4gICAgICAgICAgICAgICAgaWYgKG5leHRFbGVtLnR5cGUgPT09ICdhdHdvcmQnICYmIHByZXZFbGVtLnR5cGUgIT09ICdhdHdvcmQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcHJldkVsZW0udW5pdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvYmxlbUVsZW0gPSBwcmV2RWxlbTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIOWJjeS4gOS4quaYr+WPmOmHj1xuICAgICAgICAgICAgICAgIGlmIChwcmV2RWxlbS50eXBlID09PSAnYXR3b3JkJyAmJiBuZXh0RWxlbS50eXBlICE9PSAnYXR3b3JkJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW5leHRFbGVtLnVuaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2JsZW1FbGVtID0gbmV4dEVsZW07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocHJvYmxlbUVsZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qge3NvdXJjZSwgcHJvcCwgcmF3c30gPSBkZWNsO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsaW5lID0gc291cmNlLnN0YXJ0LmxpbmU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxpbmVDb250ZW50ID0gZ2V0TGluZUNvbnRlbnQobGluZSwgc291cmNlLmlucHV0LmNzcywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgPSBzb3VyY2Uuc3RhcnQuY29sdW1uICsgcHJvcC5sZW5ndGggKyByYXdzLmJldHdlZW4ubGVuZ3RoICsgcHJvYmxlbUVsZW0uc291cmNlLnN0YXJ0LmNvbHVtbiAtIDE7XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0Lndhcm4oUlVMRU5BTUUsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGU6IGRlY2wsXG4gICAgICAgICAgICAgICAgICAgICAgICBydWxlTmFtZTogUlVMRU5BTUUsXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lOiBsaW5lLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29sOiBjb2wsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnYCcgKyBsaW5lQ29udGVudCArICdgICcgKyBNU0csXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvck1lc3NhZ2U6ICdgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2hhbmdlQ29sb3JCeVN0YXJ0QW5kRW5kSW5kZXgobGluZUNvbnRlbnQsIGNvbCwgY29sICsgcHJvYmxlbUVsZW0udmFsdWUubGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgJ2AgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2hhbGsuZ3JleShNU0cpXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4pO1xuIl19
;