mirror of
https://github.com/thangisme/notes.git
synced 2024-11-01 04:17:33 -04:00
111 lines
2.7 KiB
JavaScript
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
|