Skip to content

Commit 1698e19

Browse files
committed
Report better errors for values parsed from a PostCSS stylesheet
Closes shellscape#98
1 parent 9e6cc98 commit 1698e19

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

lib/SubInput.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright © 2018 Andrew Powell
3+
4+
This Source Code Form is subject to the terms of the Mozilla Public
5+
License, v. 2.0. If a copy of the MPL was not distributed with this
6+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
8+
The above copyright notice and this permission notice shall be
9+
included in all copies or substantial portions of this Source Code Form.
10+
*/
11+
12+
// A PostCSS Input that exposes a substring of a larger Input as though it were
13+
// the entire text to be parsed.
14+
module.exports = class SubInput {
15+
constructor(css, context, lineInContext, columnInContext) {
16+
this.css = css;
17+
this.context = context;
18+
this.lineInContext = lineInContext;
19+
this.columnInContext = columnInContext;
20+
}
21+
22+
error(message, line, column, opts = {}) {
23+
let lineInContext;
24+
let columnInContext;
25+
if (line === 1) {
26+
lineInContext = this.lineInContext;
27+
columnInContext = column + this.columnInContext - 1;
28+
} else {
29+
lineInContext = this.lineInContext + line - 1;
30+
}
31+
32+
return this.context.error(message, lineInContext, columnInContext, opts);
33+
}
34+
35+
origin(line, column) {
36+
let lineInContext;
37+
let columnInContext;
38+
if (line === 1) {
39+
lineInContext = this.lineInContext;
40+
columnInContext = column + this.columnInContext - 1;
41+
} else {
42+
lineInContext = this.lineInContext + line - 1;
43+
}
44+
45+
return this.context.origin(lineInContext, columnInContext);
46+
}
47+
48+
mapResolve(file) {
49+
return this.context.mapResolve(file);
50+
}
51+
52+
get from() {
53+
return this.context.from;
54+
}
55+
};

lib/index.js

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,51 @@
88
The above copyright notice and this permission notice shall be
99
included in all copies or substantial portions of this Source Code Form.
1010
*/
11+
const assert = require('assert').strict;
12+
1113
const Input = require('postcss/lib/input');
1214

1315
const Parser = require('./ValuesParser');
16+
const SubInput = require('./SubInput');
1417
const { stringify } = require('./ValuesStringifier');
1518

19+
const NEWLINE = '\n'.charCodeAt(0);
20+
const FEED = '\f'.charCodeAt(0);
21+
const CR = '\r'.charCodeAt(0);
22+
23+
function positionAfter(node, chunks) {
24+
let { line } = node.source.start;
25+
let { column } = node.source.start;
26+
for (const chunk of chunks) {
27+
for (let i = 0; i < chunk.length; i++) {
28+
const code = chunk.charCodeAt(i);
29+
if (
30+
code === NEWLINE ||
31+
code === FEED ||
32+
(code === CR && chunk.charCodeAt(i + 1) !== NEWLINE)
33+
) {
34+
column = 1;
35+
line += 1;
36+
} else {
37+
column += 1;
38+
}
39+
}
40+
}
41+
42+
return { line, column };
43+
}
44+
1645
module.exports = {
1746
parse(css, options) {
18-
const input = new Input(css, options);
47+
let input;
48+
if (options.context) {
49+
assert(options.lineInContext);
50+
assert(options.columnInContext);
51+
input = new SubInput(css, options.context, options.lineInContext, options.columnInContext);
52+
} else {
53+
input = new Input(css, options);
54+
}
55+
1956
const parser = new Parser(input, options);
2057

2158
parser.parse();
@@ -32,6 +69,24 @@ module.exports = {
3269
return parser.root;
3370
},
3471

72+
parseDeclValue(decl) {
73+
const { line, column } = positionAfter(decl, [decl.prop, decl.raws.between]);
74+
return module.exports.parse(decl.value, {
75+
context: decl.source.input,
76+
lineInContext: line,
77+
columnInContext: column
78+
});
79+
},
80+
81+
parseAtRuleParams(rule) {
82+
const { line, column } = positionAfter(rule, ['@', rule.name, rule.raws.afterName]);
83+
return module.exports.parse(rule.value, {
84+
context: rule,
85+
lineInContext: line,
86+
columnInContext: column
87+
});
88+
},
89+
3590
stringify,
3691

3792
nodeToString(node) {

0 commit comments

Comments
 (0)