mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
2.8 KiB
133 lines
2.8 KiB
/**
|
|
* @fileoverview Look for useless escapes in strings and regexes
|
|
* @author Onur Temizkan
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Rule Definition
|
|
//------------------------------------------------------------------------------
|
|
|
|
const VALID_STRING_ESCAPES = [
|
|
"\\",
|
|
"n",
|
|
"r",
|
|
"v",
|
|
"t",
|
|
"b",
|
|
"f",
|
|
"u",
|
|
"x",
|
|
"\n",
|
|
"\r"
|
|
];
|
|
|
|
const VALID_REGEX_ESCAPES = [
|
|
"\\",
|
|
".",
|
|
"-",
|
|
"^",
|
|
"$",
|
|
"*",
|
|
"+",
|
|
"?",
|
|
"{",
|
|
"}",
|
|
"[",
|
|
"]",
|
|
"|",
|
|
"(",
|
|
")",
|
|
"b",
|
|
"B",
|
|
"c",
|
|
"d",
|
|
"D",
|
|
"f",
|
|
"n",
|
|
"r",
|
|
"s",
|
|
"S",
|
|
"t",
|
|
"v",
|
|
"w",
|
|
"W",
|
|
"x",
|
|
"u"
|
|
];
|
|
|
|
module.exports = {
|
|
meta: {
|
|
docs: {
|
|
description: "disallow unnecessary escape characters",
|
|
category: "Best Practices",
|
|
recommended: false
|
|
},
|
|
|
|
schema: []
|
|
},
|
|
|
|
create(context) {
|
|
|
|
/**
|
|
* Checks if the escape character in given slice is unnecessary.
|
|
*
|
|
* @private
|
|
* @param {string[]} escapes - list of valid escapes
|
|
* @param {ASTNode} node - node to validate.
|
|
* @param {string} elm - string slice to validate.
|
|
* @returns {void}
|
|
*/
|
|
function validate(escapes, node, elm) {
|
|
const escapeNotFound = escapes.indexOf(elm[0][1]) === -1;
|
|
const isQuoteEscape = elm[0][1] === node.raw[0];
|
|
|
|
if (escapeNotFound && !isQuoteEscape) {
|
|
context.report({
|
|
node,
|
|
loc: {
|
|
line: node.loc.start.line,
|
|
column: node.loc.start.column + elm.index
|
|
},
|
|
message: "Unnecessary escape character: {{character}}.",
|
|
data: {
|
|
character: elm[0]
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if a node has an escape.
|
|
*
|
|
* @param {ASTNode} node - node to check.
|
|
* @returns {void}
|
|
*/
|
|
function check(node) {
|
|
let nodeEscapes, match;
|
|
const pattern = /\\[^\d]/g;
|
|
|
|
if (typeof node.value === "string") {
|
|
|
|
// JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/
|
|
if (node.parent.type === "JSXAttribute") {
|
|
return;
|
|
}
|
|
|
|
nodeEscapes = VALID_STRING_ESCAPES;
|
|
} else if (node.regex) {
|
|
nodeEscapes = VALID_REGEX_ESCAPES;
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
while ((match = pattern.exec(node.raw))) {
|
|
validate(nodeEscapes, node, match);
|
|
}
|
|
}
|
|
return {
|
|
Literal: check
|
|
};
|
|
}
|
|
};
|
|
|