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

Refactor declaration-block-no-duplicate-properties #6545

Merged
Changes from 6 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
144 changes: 50 additions & 94 deletions lib/rules/declaration-block-no-duplicate-properties/index.js
Expand Up @@ -88,97 +88,60 @@ const rule = (primary, secondaryOptions, context) => {

const indexDuplicate = decls.findIndex((d) => d.prop.toLowerCase() === lowerProp);

if (indexDuplicate !== -1) {
const duplicateDecl = decls[indexDuplicate];
const duplicateValue = duplicateDecl ? duplicateDecl.value : '';
const duplicateImportant = duplicateDecl ? duplicateDecl.important : false;

if (ignoreDiffValues || ignorePrefixlessSameValues) {
// fails if duplicates are not consecutive
if (indexDuplicate !== decls.length - 1) {
if (context.fix) {
if (!important && duplicateImportant) {
decl.remove();
} else {
removePreviousDuplicate(decls, lowerProp);
}

return;
}

report({
message: messages.rejected(prop),
node: decl,
result,
ruleName,
word: prop,
});

return;
}

if (ignorePrefixlessSameValues) {
// fails if values of consecutive, unprefixed duplicates are equal
if (vendor.unprefixed(value) !== vendor.unprefixed(duplicateValue)) {
if (context.fix) {
if (!important && duplicateImportant) {
decl.remove();
} else {
removePreviousDuplicate(decls, lowerProp);
}

return;
}

report({
message: messages.rejected(prop),
node: decl,
result,
ruleName,
word: prop,
});

return;
}
}

// fails if values of consecutive duplicates are equal
if (value === duplicateValue) {
if (context.fix) {
removePreviousDuplicate(decls, lowerProp);

return;
}

report({
message: messages.rejected(prop),
node: decl,
result,
ruleName,
word: prop,
});

return;
}
if (indexDuplicate === -1) {
decls.push(decl);
}

return;
const duplicateDecl = decls[indexDuplicate];

if (!duplicateDecl) {
return;
}

const duplicateValue = duplicateDecl.value || '';
const duplicateImportant = duplicateDecl.important || false;
const duplicateIsMoreImportant = !important && duplicateImportant;
const duplicatesAreConsecutive = indexDuplicate === decls.length - 1;
const unprefixedDuplicatesAreEqual =
vendor.unprefixed(value) === vendor.unprefixed(duplicateValue);

function fixOrReport() {
if (!context.fix) {
return report({
message: messages.rejected(prop),
node: decl,
result,
ruleName,
word: prop,
});
}

if (ignoreDuplicates && indexDuplicate === decls.length - 1) {
return;
if (duplicateIsMoreImportant) {
return decl.remove();
}

if (context.fix) {
if (!important && duplicateImportant) {
decl.remove();
} else {
removePreviousDuplicate(decls, lowerProp);
}
if (!duplicateDecl) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either this one is not necessary or the one at l97 is
i.e. if we reach l123 duplicateDecl is true because it's a const

Copy link
Contributor

@Mouvedia Mouvedia Dec 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at l97 you have

				if (!duplicateDecl) {
					return;
				}

the l123 check is called at l133 and l157 which are after l97; since you chose to use a function declaration it's being hoisted hence it could have been called before l97.
It seems to me that duplicateDecl cannot be undefined at that stage because Boolean(undefined) === false hence it would have returned early.
If it's a type check problem you can ask @ybiquitous for help.
e.g. a /** @type … */ comment may be necessary

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remove duplicate if (!duplicateDecl) return;, we need to convert function fixOrReport to const fixOrReport. Because using function causes hoisting.

-				function fixOrReport() {
+				const fixOrReport = () => {


return duplicateDecl.remove();
}

if (ignoreDiffValues || ignorePrefixlessSameValues) {
if (
!duplicatesAreConsecutive ||
(ignorePrefixlessSameValues && !unprefixedDuplicatesAreEqual)
) {
fixOrReport();
}

if (value !== duplicateValue) {
return;
}

report({
if (context.fix) {
return duplicateDecl.remove();
}

return report({
message: messages.rejected(prop),
node: decl,
result,
Expand All @@ -187,23 +150,16 @@ const rule = (primary, secondaryOptions, context) => {
});
}

decls.push(decl);
if (ignoreDuplicates && duplicatesAreConsecutive) {
return;
}

fixOrReport();
});
});
};
};

/**
* @param {import('postcss').Declaration[]} declarations
* @param {string} lowerProperty
* @returns {void}
* */
function removePreviousDuplicate(declarations, lowerProperty) {
const declToRemove = declarations.find((d) => d.prop.toLowerCase() === lowerProperty);

if (declToRemove) declToRemove.remove();
}

rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = meta;
Expand Down