Skip to content

Commit

Permalink
From line/column to offset (#108)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
RamazanIttiev authored Nov 20, 2024
1 parent 3d41754 commit 28c39db
Show file tree
Hide file tree
Showing 12 changed files with 455 additions and 341 deletions.
60 changes: 36 additions & 24 deletions parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = class Parser {
this.prevIndent = undefined
this.step = undefined

this.root.source = { input, start: { column: 1, line: 1 } }
this.root.source = { input, start: { column: 1, line: 1, offset: 0 } }
}

atrule(part) {
Expand Down Expand Up @@ -41,21 +41,24 @@ module.exports = class Parser {
}

badProp(token) {
this.error('Unexpected separator in property', token[2], token[3])
let pos = this.getPosition(token[2])
this.error('Unexpected separator in property', pos.offset)
}

checkCurly(tokens) {
for (let token of tokens) {
if (token[0] === '{') {
this.error('Unnecessary curly bracket', token[2], token[3])
let pos = this.getPosition(token[2])
this.error('Unnecessary curly bracket', pos.offset)
}
}
}

checkSemicolon(tokens) {
for (let token of tokens) {
if (token[0] === ';') {
this.error('Unnecessary semicolon', token[2], token[3])
let pos = this.getPosition(token[2])
this.error('Unnecessary semicolon', pos.offset)
}
}
}
Expand All @@ -64,22 +67,23 @@ module.exports = class Parser {
let token = part.tokens[0]
let node = new Comment()
this.init(node, part)
node.source.end = { column: token[5], line: token[4] }
node.source.end = this.getPosition(token[3])
this.commentText(node, token)
}

/* Helpers */

commentText(node, token) {
let text = token[1]
if (token[6] === 'inline') {
if (token[4] === 'inline') {
node.raws.inline = true
text = text.slice(2)
} else {
text = text.slice(2, -2)
}

let match = text.match(/^(\s*)([^]*\S)(\s*)\n?$/)

if (match) {
node.text = match[2]
node.raws.left = match[1]
Expand Down Expand Up @@ -138,9 +142,9 @@ module.exports = class Parser {
let comment = new Comment()
this.current.push(comment)
comment.source = {
end: { column: last[5], line: last[4] },
end: this.getPosition(last[3]),
input: this.input,
start: { column: last[3], line: last[2] }
start: this.getPosition(last[2])
}
let prev = value[value.length - 1]
if (prev && prev[0] === 'space') {
Expand Down Expand Up @@ -172,8 +176,9 @@ module.exports = class Parser {
this.raw(node, 'value', value, colon)
}

error(msg, line, column) {
throw this.input.error(msg, line, column)
error(msg, offset) {
let pos = this.getPosition(offset)
throw this.input.error(msg, pos.line, pos.column)
}

firstSpaces(tokens) {
Expand All @@ -189,6 +194,15 @@ module.exports = class Parser {
return result
}

getPosition(offset) {
let pos = this.input.fromOffset(offset)
return {
column: pos.col,
line: pos.line,
offset
}
}

indent(part) {
let indent = part.indent.length
let isPrev = typeof this.prevIndent !== 'undefined'
Expand Down Expand Up @@ -227,7 +241,8 @@ module.exports = class Parser {
}

indentedFirstLine(part) {
this.error('First line should not have indent', part.number, 1)
let pos = this.getPosition(part.tokens[0][2])
this.error('First line should not have indent', pos.offset)
}

init(node, part) {
Expand All @@ -243,7 +258,7 @@ module.exports = class Parser {
}
node.source = {
input: this.input,
start: { column: part.tokens[0][3], line: part.tokens[0][2] }
start: this.getPosition(part.tokens[0][2])
}
}

Expand Down Expand Up @@ -291,10 +306,7 @@ module.exports = class Parser {
for (let i = this.tokens.length - 1; i >= 0; i--) {
if (this.tokens[i].length > 3) {
let last = this.tokens[i]
this.root.source.end = {
column: last[5] || last[3],
line: last[4] || last[2]
}
this.root.source.end = this.getPosition(last[3])
break
}
}
Expand Down Expand Up @@ -330,7 +342,7 @@ module.exports = class Parser {
if (!clean) {
let sss = tokens.reduce((all, i) => all + i[1], '')
let raw = tokens.reduce((all, i) => {
if (i[0] === 'comment' && i[6] === 'inline') {
if (i[0] === 'comment' && i[4] === 'inline') {
return all + '/* ' + i[1].slice(2).trim() + ' */'
} else {
return all + i[1]
Expand All @@ -350,10 +362,7 @@ module.exports = class Parser {
}
if (!last) last = altLast

node.source.end = {
column: last[5] || last[3],
line: last[4] || last[2]
}
node.source.end = this.getPosition(last[3])
}

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

unnamedAtrule(token) {
this.error('At-rule without name', token[2], token[3])
let pos = this.getPosition(token[2])
this.error('At-rule without name', pos.offset)
}

unnamedDecl(token) {
this.error('Declaration without name', token[2], token[3])
let pos = this.getPosition(token[2])
this.error('Declaration without name', pos.offset)
}

wrongIndent(expected, real, part) {
let pos = this.getPosition(part.tokens[0][2])
let msg = `Expected ${expected} indent, but get ${real}`
this.error(msg, part.number, 1)
this.error(msg, pos.offset)
}
}
Loading

0 comments on commit 28c39db

Please sign in to comment.