Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic fix for unused private members #952

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
200 changes: 200 additions & 0 deletions src/rules/no-unused-private-members/__tests__/index.js
Expand Up @@ -341,3 +341,203 @@ testRule({
}
]
});

testRule({
ruleName,
config: [true, { enableAutoFix: true }],
customSyntax: "postcss-scss",
fix: true,

accept: [
{
code: `
@function _addNums($n1, $n2) {
@return calc($n1 + $n2);
}

@function one($n1) {
@return $n1;
}

.sidebar {
margin-left: _addNums(4, 6);
}
`,
description: "Private function"
},
{
code: `
@mixin _reset-list {
margin: 0;
}

nav ul {
@include _reset-list;
}
`,
description: "Private mixin"
},
{
code: `
$-radius: 3px;

.rounded {
border-radius: $-radius;
}
`,
description: "Private variable"
},
{
code: `
%-toolbelt:hover {
color: red;
}

.a.%-b {
margin: 1px;
}

.action-buttons {
@extend %-toolbelt;
@extend %-b;
color: blue;
}
`,
description: "Private placeholder selector"
},
{
code: `
@import "fff"
$-radius: 3px;

rounded {
border-radius: 0px;
}
`,
message: messages.expected("$-radius"),
description: "Skip files using @import",
line: 2,
column: 7
}
],

reject: [
{
code: `
@function _addNums($n1, $n2) {
@return calc($n1 + $n2);
}

@function _one($n1) {
@return $n1;
}

.sidebar {
margin-left: _addNums(4, 6);
}
`,
fixed: `
@function _addNums($n1, $n2) {
@return calc($n1 + $n2);
}

.sidebar {
margin-left: _addNums(4, 6);
}
`,
message: messages.expected("_one"),
description: "Private function",
line: 6,
column: 7
},
{
code: `
@mixin _reset-list {
margin: 0;
padding: 0;
list-style: none;
}
nav ul {
margin: 0;
}
`,
fixed: `
nav ul {
margin: 0;
}
`,
message: messages.expected("_reset-list"),
description: "Private mixin",
line: 2,
column: 7
},
{
code: `
$-radius: 3px;

rounded {
border-radius: 0px;
}
`,
fixed: `
rounded {
border-radius: 0px;
}
`,
message: messages.expected("$-radius"),
description: "Private variable",
line: 2,
column: 7
},
{
code: `
%-toolbelt {
border-radius: 0px;
}

.b {
color: blue;
}
`,
fixed: `
.b {
color: blue;
}
`,
message: messages.expected("%-toolbelt"),
description: "Private placeholder selector",
line: 2,
column: 7
},
{
code: `
%-toolbelt:hover {
color: red;
}

.a.%-b {
margin: 1px;
}

.action-buttons {
@extend %-toolbelt;
color: blue;
}
`,
fixed: `
%-toolbelt:hover {
color: red;
}

.action-buttons {
@extend %-toolbelt;
color: blue;
}
`,
message: messages.expected("%-b"),
line: 6,
column: 9,
description: "Private placeholder selector with class"
}
]
});
28 changes: 22 additions & 6 deletions src/rules/no-unused-private-members/index.js
Expand Up @@ -3,6 +3,7 @@
const { utils } = require("stylelint");
const namespace = require("../../utils/namespace");
const ruleUrl = require("../../utils/ruleUrl");
const { isBoolean } = require("../../utils/validateTypes");

const ruleName = namespace("no-unused-private-members");

Expand All @@ -25,11 +26,22 @@ function getPrivateMembers(inputString) {
return matches;
}

function rule(primaryOption) {
function rule(primaryOption, secondaryOptions, context) {
return (root, result) => {
const validOptions = utils.validateOptions(result, ruleName, {
actual: primaryOption
});
const validOptions = utils.validateOptions(
result,
ruleName,
{
actual: primaryOption
},
{
actual: secondaryOptions,
possible: {
enableAutoFix: [isBoolean]
},
optional: true
}
);

if (!validOptions) {
return;
Expand Down Expand Up @@ -133,10 +145,14 @@ function rule(primaryOption) {
});

for (const types in privateMembers) {
for (const [key, value] of privateMembers[types].entries()) {
for (const [key, node] of privateMembers[types].entries()) {
if (context.fix && secondaryOptions?.enableAutoFix) {
node.remove();
return;
}
utils.report({
message: messages.expected(key),
node: value,
node,
result,
ruleName
});
Expand Down