Skip to content

Commit 28c39db

Browse files
From line/column to offset (#108)
* Refactored tests for tokenize.js * Refactored tokenize.js based on tests * Added offset to parser.js * Updated parse.test.js * Updated cases json files with offset * Minor fixes to pass tests * Fixed tests * Fixed tests * Fixed coverage * Fixed json prettier * Fixed coverage * Returned regexp for commentText
1 parent 3d41754 commit 28c39db

File tree

12 files changed

+455
-341
lines changed

12 files changed

+455
-341
lines changed

parser.js

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = class Parser {
1313
this.prevIndent = undefined
1414
this.step = undefined
1515

16-
this.root.source = { input, start: { column: 1, line: 1 } }
16+
this.root.source = { input, start: { column: 1, line: 1, offset: 0 } }
1717
}
1818

1919
atrule(part) {
@@ -41,21 +41,24 @@ module.exports = class Parser {
4141
}
4242

4343
badProp(token) {
44-
this.error('Unexpected separator in property', token[2], token[3])
44+
let pos = this.getPosition(token[2])
45+
this.error('Unexpected separator in property', pos.offset)
4546
}
4647

4748
checkCurly(tokens) {
4849
for (let token of tokens) {
4950
if (token[0] === '{') {
50-
this.error('Unnecessary curly bracket', token[2], token[3])
51+
let pos = this.getPosition(token[2])
52+
this.error('Unnecessary curly bracket', pos.offset)
5153
}
5254
}
5355
}
5456

5557
checkSemicolon(tokens) {
5658
for (let token of tokens) {
5759
if (token[0] === ';') {
58-
this.error('Unnecessary semicolon', token[2], token[3])
60+
let pos = this.getPosition(token[2])
61+
this.error('Unnecessary semicolon', pos.offset)
5962
}
6063
}
6164
}
@@ -64,22 +67,23 @@ module.exports = class Parser {
6467
let token = part.tokens[0]
6568
let node = new Comment()
6669
this.init(node, part)
67-
node.source.end = { column: token[5], line: token[4] }
70+
node.source.end = this.getPosition(token[3])
6871
this.commentText(node, token)
6972
}
7073

7174
/* Helpers */
7275

7376
commentText(node, token) {
7477
let text = token[1]
75-
if (token[6] === 'inline') {
78+
if (token[4] === 'inline') {
7679
node.raws.inline = true
7780
text = text.slice(2)
7881
} else {
7982
text = text.slice(2, -2)
8083
}
8184

8285
let match = text.match(/^(\s*)([^]*\S)(\s*)\n?$/)
86+
8387
if (match) {
8488
node.text = match[2]
8589
node.raws.left = match[1]
@@ -138,9 +142,9 @@ module.exports = class Parser {
138142
let comment = new Comment()
139143
this.current.push(comment)
140144
comment.source = {
141-
end: { column: last[5], line: last[4] },
145+
end: this.getPosition(last[3]),
142146
input: this.input,
143-
start: { column: last[3], line: last[2] }
147+
start: this.getPosition(last[2])
144148
}
145149
let prev = value[value.length - 1]
146150
if (prev && prev[0] === 'space') {
@@ -172,8 +176,9 @@ module.exports = class Parser {
172176
this.raw(node, 'value', value, colon)
173177
}
174178

175-
error(msg, line, column) {
176-
throw this.input.error(msg, line, column)
179+
error(msg, offset) {
180+
let pos = this.getPosition(offset)
181+
throw this.input.error(msg, pos.line, pos.column)
177182
}
178183

179184
firstSpaces(tokens) {
@@ -189,6 +194,15 @@ module.exports = class Parser {
189194
return result
190195
}
191196

197+
getPosition(offset) {
198+
let pos = this.input.fromOffset(offset)
199+
return {
200+
column: pos.col,
201+
line: pos.line,
202+
offset
203+
}
204+
}
205+
192206
indent(part) {
193207
let indent = part.indent.length
194208
let isPrev = typeof this.prevIndent !== 'undefined'
@@ -227,7 +241,8 @@ module.exports = class Parser {
227241
}
228242

229243
indentedFirstLine(part) {
230-
this.error('First line should not have indent', part.number, 1)
244+
let pos = this.getPosition(part.tokens[0][2])
245+
this.error('First line should not have indent', pos.offset)
231246
}
232247

233248
init(node, part) {
@@ -243,7 +258,7 @@ module.exports = class Parser {
243258
}
244259
node.source = {
245260
input: this.input,
246-
start: { column: part.tokens[0][3], line: part.tokens[0][2] }
261+
start: this.getPosition(part.tokens[0][2])
247262
}
248263
}
249264

@@ -291,10 +306,7 @@ module.exports = class Parser {
291306
for (let i = this.tokens.length - 1; i >= 0; i--) {
292307
if (this.tokens[i].length > 3) {
293308
let last = this.tokens[i]
294-
this.root.source.end = {
295-
column: last[5] || last[3],
296-
line: last[4] || last[2]
297-
}
309+
this.root.source.end = this.getPosition(last[3])
298310
break
299311
}
300312
}
@@ -330,7 +342,7 @@ module.exports = class Parser {
330342
if (!clean) {
331343
let sss = tokens.reduce((all, i) => all + i[1], '')
332344
let raw = tokens.reduce((all, i) => {
333-
if (i[0] === 'comment' && i[6] === 'inline') {
345+
if (i[0] === 'comment' && i[4] === 'inline') {
334346
return all + '/* ' + i[1].slice(2).trim() + ' */'
335347
} else {
336348
return all + i[1]
@@ -350,10 +362,7 @@ module.exports = class Parser {
350362
}
351363
if (!last) last = altLast
352364

353-
node.source.end = {
354-
column: last[5] || last[3],
355-
line: last[4] || last[2]
356-
}
365+
node.source.end = this.getPosition(last[3])
357366
}
358367

359368
rule(part) {
@@ -376,15 +385,18 @@ module.exports = class Parser {
376385
}
377386

378387
unnamedAtrule(token) {
379-
this.error('At-rule without name', token[2], token[3])
388+
let pos = this.getPosition(token[2])
389+
this.error('At-rule without name', pos.offset)
380390
}
381391

382392
unnamedDecl(token) {
383-
this.error('Declaration without name', token[2], token[3])
393+
let pos = this.getPosition(token[2])
394+
this.error('Declaration without name', pos.offset)
384395
}
385396

386397
wrongIndent(expected, real, part) {
398+
let pos = this.getPosition(part.tokens[0][2])
387399
let msg = `Expected ${expected} indent, but get ${real}`
388-
this.error(msg, part.number, 1)
400+
this.error(msg, pos.offset)
389401
}
390402
}

0 commit comments

Comments
 (0)