UNPKG

lesslint

Version:
126 lines (98 loc) 11.7 kB
'use strict'; 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) */ 'use strict'; /** * 规则名称 * * @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