From 4790c89305f307bbca59b4a981264606add5f6a2 Mon Sep 17 00:00:00 2001 From: Anton Evzhakov Date: Mon, 29 Nov 2021 11:09:50 +0200 Subject: [PATCH] fix(stylelint): fix indentation errors (fixes #693) --- packages/stylelint/src/index.ts | 1 - packages/stylelint/src/preprocessor.ts | 83 +++++++++++++++++--------- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/packages/stylelint/src/index.ts b/packages/stylelint/src/index.ts index 1794dcb54..fbf105568 100644 --- a/packages/stylelint/src/index.ts +++ b/packages/stylelint/src/index.ts @@ -7,6 +7,5 @@ export default { 'value-no-vendor-prefix': true, 'no-empty-source': null, 'no-extra-semicolons': null, - 'no-missing-end-of-source-newline': null, }, }; diff --git a/packages/stylelint/src/preprocessor.ts b/packages/stylelint/src/preprocessor.ts index 9e9945ca8..a83ce06e9 100644 --- a/packages/stylelint/src/preprocessor.ts +++ b/packages/stylelint/src/preprocessor.ts @@ -35,9 +35,21 @@ type LintResult = { warnings: Warning[]; }; +interface IPosition { + line: number; + column: number; +} + +interface ISourceOffset { + generated: IPosition; + name: string; + original: IPosition; +} + function preprocessor() { const errors: Errors = {}; const cache: Cache = {}; + const offsets: Record = {}; return { code(input: string, filename: string) { @@ -50,8 +62,10 @@ function preprocessor() { cache[filename] = undefined; errors[filename] = undefined; + offsets[filename] = []; } catch (e) { cache[filename] = undefined; + offsets[filename] = undefined; errors[filename] = e; // Ignore parse errors here @@ -66,41 +80,55 @@ function preprocessor() { } // Construct a CSS-ish file from the unprocessed style rules - let cssText = ''; - - Object.keys(rules).forEach((selector) => { - const rule = rules[selector]; - - // Append new lines until we get to the start line number - let line = cssText.split('\n').length; - - while (rule.start && line < rule.start.line) { - cssText += '\n'; - line++; - } - - cssText += `.${rule.displayName} {`; - - // Append blank spaces until we get to the start column number - const last = cssText.split('\n').pop(); - - let column = last ? last.length : 0; - - while (rule.start && column < rule.start.column) { - cssText += ' '; - column++; - } + let generatedLineNumber = 1; + let cssText = Object.values(rules) + .map((rule) => { + const ruleText = `.${rule.className} {${rule.cssText}}`; + + if (rule.start && 'line' in rule.start) { + offsets[filename]?.push({ + generated: { + line: generatedLineNumber, + column: 1, + }, + original: { + ...rule.start, + }, + name: rule.displayName, + }); + + generatedLineNumber += 1; + } - cssText += `${rule.cssText} }`; - }); + generatedLineNumber += ruleText.split('\n').length + 2; + return ruleText; + }) + .join('\n\n'); cache[filename] = replacements; + offsets[filename] = offsets[filename]?.reverse(); + + console.log(cssText); - return cssText; + return cssText + '\n'; }, result(result: LintResult, filename: string) { const error = errors[filename]; const replacements = cache[filename]; + const sourceMap = offsets[filename]; + + if (sourceMap) { + result.warnings = result.warnings.map((warning) => { + const offset = sourceMap.find( + (o) => o.generated.line <= warning.line + ); + if (offset) { + warning.line += offset.original.line - offset.generated.line; + } + + return warning; + }); + } if (error) { // Babel adds this to the error message @@ -150,7 +178,6 @@ function preprocessor() { // Correct the line and column numbers to what's replaced result.warnings.forEach((w) => { /* eslint-disable no-param-reassign */ - if (w.line === original.start.line) { // If the error is on the same line where an interpolation started, we need to adjust the line and column numbers // Because a replacement would have increased or decreased the column numbers