Skip to content

Commit 5a8adb7

Browse files
authored
Calculate the correct range of CSS syntax errors (#196)
* update postcss * update snapshot * add test * calculate the correct range of CSS syntax errors * add changelog
1 parent 90ddb64 commit 5a8adb7

7 files changed

Lines changed: 87 additions & 26 deletions

File tree

.changeset/modern-turtles-give.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@css-modules-kit/codegen': patch
3+
'@css-modules-kit/core': patch
4+
---
5+
6+
fix: calculate the correct range of CSS syntax errors

package-lock.json

Lines changed: 21 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/codegen/e2e/index.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { spawnSync } from 'node:child_process';
2+
import { stripVTControlCharacters } from 'node:util';
23
import { join } from '@css-modules-kit/core';
34
import dedent from 'dedent';
45
import { expect, test } from 'vitest';
@@ -87,6 +88,23 @@ test('prints version number', () => {
8788
expect(cmk.status).toBe(0);
8889
});
8990

91+
test('reports CSS syntax error', async () => {
92+
const iff = await createIFF({
93+
'src/a.module.css': `badword`,
94+
'tsconfig.json': '{}',
95+
});
96+
const cmk = spawnSync('node', [binPath, '--pretty'], { cwd: iff.rootDir });
97+
expect(cmk.status).toBe(1);
98+
expect(stripVTControlCharacters(cmk.stderr.toString())).toMatchInlineSnapshot(`
99+
"src/a.module.css:1:1 - error: Unknown word badword
100+
101+
1 badword
102+
~~~~~~~
103+
104+
"
105+
`);
106+
});
107+
90108
test('reports system error', async () => {
91109
const iff = await createIFF({});
92110
const cmk = spawnSync('node', [binPath], {

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"dist"
4444
],
4545
"dependencies": {
46-
"postcss": "^8.4.49",
46+
"postcss": "^8.5.5",
4747
"postcss-safe-parser": "^7.0.1",
4848
"postcss-selector-parser": "^7.1.0",
4949
"postcss-value-parser": "^4.2.0"

packages/core/src/parser/css-module-parser.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,31 @@ describe('parseCSSModule', () => {
495495
],
496496
}
497497
`);
498+
expect(parseCSSModule('badword', options)).toMatchInlineSnapshot(`
499+
{
500+
"cssModule": {
501+
"fileName": "/test.module.css",
502+
"localTokens": [],
503+
"text": "badword",
504+
"tokenImporters": [],
505+
},
506+
"diagnostics": [
507+
{
508+
"category": "error",
509+
"file": {
510+
"fileName": "/test.module.css",
511+
"text": "badword",
512+
},
513+
"length": 7,
514+
"start": {
515+
"column": 1,
516+
"line": 1,
517+
},
518+
"text": "Unknown word badword",
519+
},
520+
],
521+
}
522+
`);
498523
});
499524
test('parses CSS in a fault-tolerant manner if safe is true', () => {
500525
const parsed = parseCSSModule(

packages/core/src/parser/css-module-parser.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,14 @@ export function parseCSSModule(text: string, { fileName, safe }: ParseCSSModuleO
8282
ast = parser(text, { from: fileName });
8383
} catch (e) {
8484
if (e instanceof CssSyntaxError) {
85-
const start = { line: e.line ?? 1, column: e.column ?? 1 };
85+
const { line, column, endColumn } = e.input!;
8686
return {
8787
cssModule: { fileName, text, localTokens: [], tokenImporters: [] },
8888
diagnostics: [
8989
{
9090
file: diagnosticSourceFile,
91-
start,
92-
// TODO: Assign correct length (e.g. `e.endOffset - e.offset`)
93-
length: 1,
91+
start: { line, column },
92+
length: endColumn !== undefined ? endColumn - column : 1,
9493
text: e.reason,
9594
category: 'error',
9695
},

packages/core/src/parser/rule-parser.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
5656
"start": {
5757
"column": 3,
5858
"line": 1,
59+
"offset": 2,
5960
},
6061
"type": "combinator",
6162
},
@@ -65,6 +66,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
6566
"start": {
6667
"column": 4,
6768
"line": 1,
69+
"offset": 3,
6870
},
6971
"type": "class",
7072
},
@@ -108,6 +110,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
108110
"start": {
109111
"column": 3,
110112
"line": 1,
113+
"offset": 2,
111114
},
112115
"type": "combinator",
113116
},
@@ -117,6 +120,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
117120
"start": {
118121
"column": 1,
119122
"line": 2,
123+
"offset": 3,
120124
},
121125
"type": "class",
122126
},
@@ -127,6 +131,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
127131
"start": {
128132
"column": 3,
129133
"line": 2,
134+
"offset": 5,
130135
},
131136
"type": "combinator",
132137
},
@@ -136,6 +141,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
136141
"start": {
137142
"column": 3,
138143
"line": 3,
144+
"offset": 8,
139145
},
140146
"type": "class",
141147
},
@@ -176,6 +182,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
176182
"start": {
177183
"column": 3,
178184
"line": 2,
185+
"offset": 24,
179186
},
180187
"type": "combinator",
181188
},
@@ -185,6 +192,7 @@ describe('calcDiagnosticsLocationForSelectorParserNode', () => {
185192
"start": {
186193
"column": 3,
187194
"line": 3,
195+
"offset": 27,
188196
},
189197
"type": "class",
190198
},
@@ -571,6 +579,7 @@ describe('parseRule', () => {
571579
"start": {
572580
"column": 8,
573581
"line": 1,
582+
"offset": 7,
574583
},
575584
"text": "A \`:global(...)\` is not allowed inside of \`:local(...)\`.",
576585
},
@@ -585,6 +594,7 @@ describe('parseRule', () => {
585594
"start": {
586595
"column": 9,
587596
"line": 2,
597+
"offset": 31,
588598
},
589599
"text": "A \`:local(...)\` is not allowed inside of \`:global(...)\`.",
590600
},
@@ -599,6 +609,7 @@ describe('parseRule', () => {
599609
"start": {
600610
"column": 8,
601611
"line": 3,
612+
"offset": 53,
602613
},
603614
"text": "A \`:local(...)\` is not allowed inside of \`:local(...)\`.",
604615
},
@@ -613,6 +624,7 @@ describe('parseRule', () => {
613624
"start": {
614625
"column": 9,
615626
"line": 4,
627+
"offset": 76,
616628
},
617629
"text": "A \`:global(...)\` is not allowed inside of \`:global(...)\`.",
618630
},
@@ -781,6 +793,7 @@ describe('parseRule', () => {
781793
"start": {
782794
"column": 6,
783795
"line": 1,
796+
"offset": 5,
784797
},
785798
"text": "\`a_\\u0032\` is not allowed because it is not a valid JavaScript identifier.",
786799
},

0 commit comments

Comments
 (0)