1
0
mirror of https://github.com/thangisme/notes.git synced 2024-06-28 15:25:31 +00:00
notes/node_modules/stylelint/lib/rules/no-extra-semicolons/index.js
Patrick Marsceill b7b0d0d7bf
Initial commit
2017-03-09 13:16:08 -05:00

111 lines
2.7 KiB
JavaScript

"use strict"
const hasEmptyBlock = require("../../utils/hasEmptyBlock")
const isCustomPropertySet = require("../../utils/isCustomPropertySet")
const report = require("../../utils/report")
const ruleMessages = require("../../utils/ruleMessages")
const validateOptions = require("../../utils/validateOptions")
const styleSearch = require("style-search")
const ruleName = "no-extra-semicolons"
const messages = ruleMessages(ruleName, {
rejected: "Unexpected extra semicolon",
})
function getOffsetByNode(node) {
const string = node.root().toString()
const nodeColumn = node.source.start.column
const nodeLine = node.source.start.line
let line = 1
let column = 1
let index = 0
for (let i = 0; i < string.length; i++) {
if (column === nodeColumn && nodeLine === line) {
index = i
break
}
if (string[i] === "\n") {
column = 1
line += 1
} else {
column += 1
}
}
return index
}
const rule = function (actual) {
return (root, result) => {
const validOptions = validateOptions(result, ruleName, { actual })
if (!validOptions) {
return
}
const rawAfterRoot = root.raws.after
if (rawAfterRoot && rawAfterRoot.trim().length !== 0) {
styleSearch({ source: rawAfterRoot, target: ";" }, match => {
complain(root.toString().length - rawAfterRoot.length + match.startIndex)
})
}
root.walk(node => {
const rawBeforeNode = node.raws.before
if (rawBeforeNode && rawBeforeNode.trim().length !== 0) {
let allowedSemi = 0
// Forbid semicolon before first custom properties sets
if (isCustomPropertySet(node) && node.parent.index(node) > 0) {
allowedSemi = 1
}
styleSearch({ source: rawBeforeNode, target: ";" }, (match, count) => {
if (count === allowedSemi) {
return
}
complain(getOffsetByNode(node) - rawBeforeNode.length + match.startIndex)
})
}
const rawAfterNode = node.raws.after
if (rawAfterNode && rawAfterNode.trim().length !== 0) {
let allowedSemi = 0
if (!hasEmptyBlock(node) && isCustomPropertySet(node.nodes[node.nodes.length - 1])) {
allowedSemi = 1
}
styleSearch({ source: rawAfterNode, target: ";" }, (match, count) => {
if (count === allowedSemi) {
return
}
const index = getOffsetByNode(node) + node.toString().length - 1 - rawAfterNode.length + match.startIndex
complain(index)
})
}
})
function complain(index) {
report({
message: messages.rejected,
node: root,
index,
result,
ruleName,
})
}
}
}
rule.ruleName = ruleName
rule.messages = messages
module.exports = rule