Skip to content

Commit

Permalink
Refactor to turn on noUncheckedIndexedAccess option for TypeScript (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ybiquitous committed Apr 19, 2022
1 parent 55a8daf commit b013ac0
Show file tree
Hide file tree
Showing 54 changed files with 224 additions and 138 deletions.
2 changes: 1 addition & 1 deletion lib/augmentConfig.js
Expand Up @@ -318,7 +318,7 @@ function addPluginFunctions(config) {

const normalizedPlugins = [config.plugins].flat();

/** @type {{[k: string]: Function}} */
/** @type {StylelintConfig['pluginFunctions']} */
const pluginFunctions = {};

for (const pluginLookup of normalizedPlugins) {
Expand Down
6 changes: 2 additions & 4 deletions lib/descriptionlessDisables.js
Expand Up @@ -22,13 +22,11 @@ module.exports = function descriptionlessDisables(results) {

const [enabled, options, stylelintResult] = settings;

const rangeData = stylelintResult.disabledRanges;

/** @type {Set<PostcssComment>} */
const alreadyReported = new Set();

for (const rule of Object.keys(rangeData)) {
for (const range of rangeData[rule]) {
for (const [rule, ruleRanges] of Object.entries(stylelintResult.disabledRanges)) {
for (const range of ruleRanges) {
if (range.description) continue;

if (alreadyReported.has(range.comment)) continue;
Expand Down
16 changes: 12 additions & 4 deletions lib/formatters/stringFormatter.js
Expand Up @@ -4,6 +4,8 @@ const path = require('path');
const stringWidth = require('string-width');
const table = require('table');
const { yellow, dim, underline, blue, red, green } = require('picocolors');

const { assertNumber } = require('../utils/validateTypes');
const terminalLink = require('./terminalLink');

const MARGIN_WIDTHS = 9;
Expand Down Expand Up @@ -98,19 +100,23 @@ function logFrom(fromValue, cwd) {
* @return {number}
*/
function getMessageWidth(columnWidths) {
const width = columnWidths[3];

assertNumber(width);

if (!process.stdout.isTTY) {
return columnWidths[3];
return width;
}

const availableWidth = process.stdout.columns < 80 ? 80 : process.stdout.columns;
const fullWidth = Object.values(columnWidths).reduce((a, b) => a + b);

// If there is no reason to wrap the text, we won't align the last column to the right
if (availableWidth > fullWidth + MARGIN_WIDTHS) {
return columnWidths[3];
return width;
}

return availableWidth - (fullWidth - columnWidths[3] + MARGIN_WIDTHS);
return availableWidth - (fullWidth - width + MARGIN_WIDTHS);
}

/**
Expand Down Expand Up @@ -154,8 +160,10 @@ function formatter(messages, source, cwd) {
function calculateWidths(columns) {
for (const [key, value] of Object.entries(columns)) {
const normalisedValue = value ? value.toString() : value;
const width = columnWidths[key];

columnWidths[key] = Math.max(columnWidths[key], stringWidth(normalisedValue));
assertNumber(width);
columnWidths[key] = Math.max(width, stringWidth(normalisedValue));
}

return columns;
Expand Down
7 changes: 4 additions & 3 deletions lib/formatters/verboseFormatter.js
Expand Up @@ -78,12 +78,13 @@ function groupBy(array, keyFn) {

for (const item of array) {
const key = keyFn(item);
let warnings = result[key];

if (!(key in result)) {
result[key] = [];
if (warnings === undefined) {
result[key] = warnings = [];
}

result[key].push(item);
warnings.push(item);
}

return result;
Expand Down
7 changes: 2 additions & 5 deletions lib/invalidScopeDisables.js
Expand Up @@ -22,15 +22,12 @@ module.exports = function invalidScopeDisables(results) {

usedRules.add('all');

const rangeData = stylelintResult.disabledRanges;
const disabledRules = Object.keys(rangeData);

for (const rule of disabledRules) {
for (const [rule, ruleRanges] of Object.entries(stylelintResult.disabledRanges)) {
if (usedRules.has(rule)) continue;

if (enabled === optionsMatches(options, 'except', rule)) continue;

for (const range of rangeData[rule]) {
for (const range of ruleRanges) {
if (!range.strictStart && !range.strictEnd) continue;

// If the comment doesn't have a location, we can't report a useful error.
Expand Down
2 changes: 1 addition & 1 deletion lib/lintPostcssResult.js
Expand Up @@ -129,7 +129,7 @@ function lintPostcssResult(stylelintOptions, postcssResult, config) {
*/
function isFixCompatible({ stylelint }) {
// Check for issue #2643
if (stylelint.disabledRanges.all.length) return false;
if (stylelint.disabledRanges.all && stylelint.disabledRanges.all.length) return false;

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/needlessDisables.js
Expand Up @@ -46,14 +46,14 @@ module.exports = function needlessDisables(results) {
}
}

for (const range of rangeData.all) {
for (const range of rangeData.all || []) {
if (isWarningInRange(warning, range)) {
putIfAbsent(usefulDisables, range.comment, () => new Set()).add(rule);
}
}
}

const allRangeComments = new Set(rangeData.all.map((range) => range.comment));
const allRangeComments = new Set((rangeData.all || []).map((range) => range.comment));

for (const [rule, ranges] of Object.entries(rangeData)) {
for (const range of ranges) {
Expand Down
5 changes: 2 additions & 3 deletions lib/printConfig.js
Expand Up @@ -19,15 +19,14 @@ module.exports = async function printConfig({
files,
}) {
const isCodeNotFile = code !== undefined;
const filePath = files && files[0];

if (!files || files.length !== 1 || isCodeNotFile) {
if (!files || files.length !== 1 || !filePath || isCodeNotFile) {
return Promise.reject(
new Error('The --print-config option must be used with exactly one file path.'),
);
}

const filePath = files[0];

if (globby.hasMagic(filePath)) {
return Promise.reject(new Error('The --print-config option does not support globs.'));
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/color-hex-length/index.js
Expand Up @@ -117,7 +117,7 @@ function longer(hex) {
let hexVariant = '#';

for (let i = 1; i < hex.length; i++) {
hexVariant += hex[i] + hex[i];
hexVariant += hex.charAt(i).repeat(2);
}

return hexVariant;
Expand Down
4 changes: 2 additions & 2 deletions lib/rules/color-named/colordUtils.js
Expand Up @@ -43,7 +43,7 @@ function parseHwbWithCommaString(input) {

const [hue, whiteness = '', blackness = '', alpha, ...extraArgs] = input.slice(4, -1).split(',');

if (!hue.trim() || !whiteness.trim() || !blackness.trim() || extraArgs.length > 0) {
if (!hue || !hue.trim() || !whiteness.trim() || !blackness.trim() || extraArgs.length > 0) {
return null;
}

Expand Down Expand Up @@ -72,7 +72,7 @@ function parseGrayString(input) {

const [lightness, alpha, ...extraArgs] = input.slice(5, -1).split(',');

if (extraArgs.length > 0) {
if (!lightness || extraArgs.length > 0) {
return null;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/rules/color-no-invalid-hex/index.js
Expand Up @@ -43,7 +43,7 @@ const rule = (primary) => {

const hexValue = hexMatch[0];

if (isValidHex(hexValue)) return;
if (!hexValue || isValidHex(hexValue)) return;

const index = declarationValueIndex(decl) + sourceIndex;
const endIndex = index + hexValue.length;
Expand Down
8 changes: 6 additions & 2 deletions lib/rules/comment-whitespace-inside/index.js
Expand Up @@ -68,11 +68,15 @@ const rule = (primary, _secondaryOptions, context) => {

const leftMatches = rawComment.match(/(^\/\*+)(\s)?/);

if (leftMatches == null) throw new Error(`Invalid comment: "${rawComment}"`);
if (leftMatches == null || leftMatches[1] == null) {
throw new Error(`Invalid comment: "${rawComment}"`);
}

const rightMatches = rawComment.match(/(\s)?(\*+\/)$/);

if (rightMatches == null) throw new Error(`Invalid comment: "${rawComment}"`);
if (rightMatches == null || rightMatches[2] == null) {
throw new Error(`Invalid comment: "${rawComment}"`);
}

const opener = leftMatches[1];
const leftSpace = leftMatches[2] || '';
Expand Down
4 changes: 3 additions & 1 deletion lib/rules/custom-media-pattern/index.js
Expand Up @@ -37,7 +37,9 @@ const rule = (primary) => {

const match = atRule.params.match(/^--(\S+)\b/);

if (match == null) throw new Error(`Unexpected at-rule params: "${atRule.params}"`);
if (match == null || match[0] == null) {
throw new Error(`Unexpected at-rule params: "${atRule.params}"`);
}

const customMediaName = match[1];

Expand Down
Expand Up @@ -101,7 +101,7 @@ const rule = (primary, secondaryOptions) => {
return;
}

const duplicateValue = values[indexDuplicate];
const duplicateValue = values[indexDuplicate] || '';

if (ignorePrefixlessSameValues) {
// fails if values of consecutive, unprefixed duplicates are equal
Expand Down
Expand Up @@ -72,23 +72,19 @@ const rule = (primary, secondaryOptions) => {

for (const shorthandProperty of shorthandProperties) {
const prefixedShorthandProperty = prefix + shorthandProperty;
let longhandDeclaration = longhandDeclarations[prefixedShorthandProperty];

if (!longhandDeclarations[prefixedShorthandProperty]) {
longhandDeclarations[prefixedShorthandProperty] = [];
if (!longhandDeclaration) {
longhandDeclaration = longhandDeclarations[prefixedShorthandProperty] = [];
}

longhandDeclarations[prefixedShorthandProperty].push(prop);
longhandDeclaration.push(prop);

const prefixedShorthandData = shorthandData[shorthandProperty].map(
const prefixedShorthandData = (shorthandData[shorthandProperty] || []).map(
(item) => prefix + item,
);

if (
!arrayEqual(
prefixedShorthandData.sort(),
longhandDeclarations[prefixedShorthandProperty].sort(),
)
) {
if (!arrayEqual(prefixedShorthandData.sort(), longhandDeclaration.sort())) {
continue;
}

Expand Down
Expand Up @@ -52,7 +52,7 @@ const rule = (primary) => {
ruleName,
result,
node: decl,
message: messages.rejected(prop, declarations[prefix + longhandProp]),
message: messages.rejected(prop, declarations[prefix + longhandProp] || ''),
});
}
});
Expand Down
4 changes: 3 additions & 1 deletion lib/rules/declaration-property-max-values/index.js
Expand Up @@ -7,7 +7,7 @@ const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
const vendor = require('../../utils/vendor');
const validateOptions = require('../../utils/validateOptions');
const { isNumber } = require('../../utils/validateTypes');
const { isNumber, assertNumber } = require('../../utils/validateTypes');
const validateObjectWithProps = require('../../utils/validateObjectWithProps');

const ruleName = 'declaration-property-max-values';
Expand Down Expand Up @@ -55,6 +55,8 @@ const rule = (primary) => {

const max = primary[propKey];

assertNumber(max);

if (propLength <= max) {
return;
}
Expand Down
15 changes: 11 additions & 4 deletions lib/rules/function-calc-no-unspaced-operator/index.js
Expand Up @@ -8,6 +8,7 @@ const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
const setDeclarationValue = require('../../utils/setDeclarationValue');
const validateOptions = require('../../utils/validateOptions');
const { assert } = require('../../utils/validateTypes');

const ruleName = 'function-calc-no-unspaced-operator';

Expand Down Expand Up @@ -56,8 +57,11 @@ const rule = (primary, _secondaryOptions, context) => {
function checkAroundOperator(nodes, operatorIndex, direction) {
const isBeforeOp = direction === -1;
const currentNode = nodes[operatorIndex + direction];
const operator = nodes[operatorIndex].value;
const operatorSourceIndex = nodes[operatorIndex].sourceIndex;
const node = nodes[operatorIndex];

assert(node);
const operator = node.value;
const operatorSourceIndex = node.sourceIndex;

if (currentNode && !isSingleSpace(currentNode)) {
if (currentNode.type === 'word') {
Expand Down Expand Up @@ -168,6 +172,7 @@ const rule = (primary, _secondaryOptions, context) => {
function checkForOperatorInFirstNode(nodes) {
const firstNode = nodes[0];

assert(firstNode);
const operatorIndex =
(firstNode.type === 'word' || -1) && firstNode.value.search(OPERATOR_REGEX);
const operator = firstNode.value.slice(operatorIndex, operatorIndex + 1);
Expand Down Expand Up @@ -233,6 +238,7 @@ const rule = (primary, _secondaryOptions, context) => {

const lastNode = nodes[nodes.length - 1];

assert(lastNode);
const operatorIndex =
(lastNode.type === 'word' || -1) && lastNode.value.search(OPERATOR_REGEX);

Expand All @@ -248,6 +254,7 @@ const rule = (primary, _secondaryOptions, context) => {

const operator = lastNode.value[operatorIndex];

assert(operator);
complain(
messages.expectedOperatorBeforeSign(operator),
decl,
Expand Down Expand Up @@ -337,11 +344,11 @@ function insertCharAtIndex(str, index, char) {
}

/**
* @param {import('postcss-value-parser').Node} node
* @param {import('postcss-value-parser').Node | undefined} node
* @returns {node is import('postcss-value-parser').SpaceNode & { value: ' ' } }
*/
function isSingleSpace(node) {
return node && node.type === 'space' && node.value === ' ';
return node != null && node.type === 'space' && node.value === ' ';
}

rule.ruleName = ruleName;
Expand Down
Expand Up @@ -66,15 +66,15 @@ const rule = (primary) => {
/^(-webkit-|-moz-|-o-)?linear-gradient$/i,
(expression, expressionIndex) => {
const args = expression.split(',');
const firstArg = args[0].trim();
const firstArg = (args[0] || '').trim();

// If the first arg is not standard, return early
if (!isStandardSyntaxValue(firstArg)) {
return;
}

// If the first character is a number, we can assume the user intends an angle
if (/[\d.]/.test(firstArg[0])) {
if (/[\d.]/.test(firstArg.charAt(0))) {
if (/^[\d.]+(?:deg|grad|rad|turn)$/.test(firstArg)) {
return;
}
Expand All @@ -99,7 +99,7 @@ const rule = (primary) => {

function complain() {
const index = declarationValueIndex(decl) + valueNode.sourceIndex + expressionIndex;
const endIndex = index + args[0].trimEnd().length;
const endIndex = index + (args[0] || '').trimEnd().length;

report({
message: messages.rejected,
Expand Down
9 changes: 7 additions & 2 deletions lib/rules/function-whitespace-after/index.js
Expand Up @@ -62,7 +62,9 @@ const rule = (primary, _secondaryOptions, context) => {
* @param {((index: number) => void) | undefined} fix
*/
function checkClosingParen(source, index, node, nodeIndex, fix) {
const nextChar = source[index];
const nextChar = source.charAt(index);

if (!nextChar) return;

if (primary === 'always') {
// Allow for the next character to be a single empty space,
Expand Down Expand Up @@ -132,7 +134,10 @@ const rule = (primary, _secondaryOptions, context) => {
applyFix = (index) => {
let whitespaceEndIndex = index + 1;

while (whitespaceEndIndex < value.length && isWhitespace(value[whitespaceEndIndex])) {
while (
whitespaceEndIndex < value.length &&
isWhitespace(value.charAt(whitespaceEndIndex))
) {
whitespaceEndIndex++;
}

Expand Down

0 comments on commit b013ac0

Please sign in to comment.