Skip to content

Commit

Permalink
fix: trim leading newline
Browse files Browse the repository at this point in the history
We trim this so we don't trigger stylelint's rules which disallow empty
first lines. In JS sources, an empty first line makes sense.

We also have to set `beforeStart` explicitly on the root's raws until
stylelint fixes stylelint/stylelint#5767.
  • Loading branch information
43081j committed Dec 7, 2021
1 parent 9042542 commit 47dc4d2
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 11 deletions.
20 changes: 13 additions & 7 deletions src/locationCorrection.ts
Expand Up @@ -5,7 +5,8 @@ import {createPlaceholder} from './util.js';
const correctLocation = (
node: TaggedTemplateExpression,
loc: Position,
baseIndentations: Map<number, number>
baseIndentations: Map<number, number>,
prefixOffsets?: {lines: number; offset: number}
): Position => {
if (!node.quasi.loc || !node.quasi.range) {
return loc;
Expand All @@ -19,6 +20,11 @@ const correctLocation = (
let currentLine = 1;
let columnOffset = nodeLoc.start.column + 1;

if (prefixOffsets) {
lineOffset += prefixOffsets.lines;
newOffset += prefixOffsets.offset;
}

for (let i = 0; i < node.quasi.expressions.length; i++) {
const expr = node.quasi.expressions[i];
const previousQuasi = node.quasi.quasis[i];
Expand Down Expand Up @@ -72,9 +78,7 @@ const correctLocation = (
if (loc.line === currentLine) {
loc.column += columnOffset;
}
if (loc.line !== 1) {
loc.column += baseIndentation;
}
loc.column += baseIndentation;

loc.offset = newOffset + indentationOffset;

Expand All @@ -94,7 +98,7 @@ function computeBeforeAfter(
): void {
if (
node.raws['before'] &&
node.raws['before'].includes('\n') &&
(node.raws['before'].includes('\n') || node.parent?.type === 'root') &&
node.source?.start
) {
const raw = node.raws['before'];
Expand Down Expand Up @@ -140,14 +144,16 @@ export function locationCorrectionWalker(
node.source.start = correctLocation(
expr,
node.source.start,
baseIndentations
baseIndentations,
root.raws['litPrefixOffsets']
);
}
if (node.source?.end) {
node.source.end = correctLocation(
expr,
node.source.end,
baseIndentations
baseIndentations,
root.raws['litPrefixOffsets']
);
}
};
Expand Down
20 changes: 19 additions & 1 deletion src/parse.ts
Expand Up @@ -70,7 +70,15 @@ export const parse: Parser<Root | Document> = (
const sourceLines = styleText.split('\n');
const baseIndentations = new Map<number, number>();
const indentationPattern = new RegExp(`^[ \\t]{${baseIndentation}}`);
const emptyLinePattern = /^[ \\t\r]*$/;
const deindentedLines: string[] = [];
const prefixOffsets = {lines: 0, offset: 0};

if (sourceLines[0] !== undefined && emptyLinePattern.test(sourceLines[0])) {
prefixOffsets.lines = 1;
prefixOffsets.offset = sourceLines[0].length + 1;
sourceLines.shift();
}

for (let i = 0; i < sourceLines.length; i++) {
const sourceLine = sourceLines[i];
Expand All @@ -95,9 +103,19 @@ export const parse: Parser<Root | Document> = (
map: false
}) as Root;

root.raws['litPrefixOffsets'] = prefixOffsets;
root.raws['litTemplateExpressions'] = expressionStrings;
root.raws['litBaseIndentations'] = baseIndentations;
root.raws.codeBefore = sourceAsString.slice(currentOffset, startIndex);
// TODO (43081j): remove this if stylelint/stylelint#5767 ever gets fixed,
// or they drop the indentation rule. Their indentation rule depends on
// `beforeStart` existing as they unsafely try to call `endsWith` on it.
if (!root.raws['beforeStart']) {
root.raws['beforeStart'] = '';
}
root.raws.codeBefore = sourceAsString.slice(
currentOffset,
startIndex + prefixOffsets.offset
);
root.parent = doc;
// TODO (43081j): stylelint relies on this existing, really unsure why.
// it could just access root.parent to get the document...
Expand Down
4 changes: 2 additions & 2 deletions src/test/parse_test.ts
Expand Up @@ -16,7 +16,7 @@ describe('parse', () => {
assert.equal(root.type, 'root');
assert.equal(rule.type, 'rule');
assert.equal(colour.type, 'decl');
assert.equal(root.raws.codeBefore, '\n css`');
assert.equal(root.raws.codeBefore, '\n css`\n');
assert.equal(root.parent, ast);
assert.equal(root.raws.codeAfter, '`;\n ');
assert.deepEqual(ast.source!.start, {
Expand Down Expand Up @@ -73,7 +73,7 @@ describe('parse', () => {
const root2 = ast.nodes[1] as Root;

assert.equal(root1.type, 'root');
assert.equal(root1.raws.codeBefore, '\n css`');
assert.equal(root1.raws.codeBefore, '\n css`\n');
assert.equal(root1.raws.codeAfter, undefined);
assert.equal(root1.parent, ast);
assert.equal(root2.type, 'root');
Expand Down
2 changes: 1 addition & 1 deletion src/test/postcss_test.ts
Expand Up @@ -25,7 +25,7 @@ describe('postcss', () => {
assert.equal(root.type, 'root');
assert.equal(rule.type, 'rule');
assert.equal(colour.type, 'decl');
assert.equal(root.raws.codeBefore, '\n css`');
assert.equal(root.raws.codeBefore, '\n css`\n');
assert.equal(root.parent, ast);
assert.equal(root.raws.codeAfter, '`;\n ');
assert.deepEqual(ast.source!.start, {
Expand Down

0 comments on commit 47dc4d2

Please sign in to comment.