ember-eslint-parser
Advanced tools
Comparing version 0.2.3 to 0.2.4
{ | ||
"name": "ember-eslint-parser", | ||
"version": "0.2.3", | ||
"version": "0.2.4", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "keywords": [], |
@@ -9,2 +9,27 @@ const ContentTag = require('content-tag'); | ||
const BufferMap = new Map(); | ||
function getBuffer(str) { | ||
let buf = BufferMap.get(str); | ||
if (!buf) { | ||
buf = Buffer.from(str); | ||
BufferMap.set(str, buf); | ||
} | ||
return buf; | ||
} | ||
function sliceByteRange(str, a, b) { | ||
const buf = getBuffer(str); | ||
return buf.slice(a, b).toString(); | ||
} | ||
function byteToCharIndex(str, byteOffset) { | ||
const buf = getBuffer(str); | ||
return buf.slice(0, byteOffset + 1).toString().length - 1; | ||
} | ||
function byteLength(str) { | ||
return getBuffer(str).length; | ||
} | ||
/** | ||
@@ -206,2 +231,3 @@ * finds the nearest node scope | ||
templateRange: [r.range.start, r.range.end], | ||
utf16Range: [byteToCharIndex(code, r.range.start), byteToCharIndex(code, r.range.end)], | ||
})); | ||
@@ -211,9 +237,14 @@ const templateVisitorKeys = {}; | ||
const comments = []; | ||
const textNodes = []; | ||
for (const tpl of templateInfos) { | ||
const currentComments = []; | ||
const textNodes = []; | ||
const range = tpl.range; | ||
const template = code.slice(...range); | ||
const template = sliceByteRange(code, ...range); | ||
const docLines = new DocumentLines(template); | ||
const ast = glimmer.preprocess(template, { mode: 'codemod' }); | ||
ast.tokens = tokenize(code.slice(...tpl.templateRange), codeLines, tpl.templateRange[0]); | ||
ast.tokens = tokenize( | ||
sliceByteRange(code, ...tpl.templateRange), | ||
codeLines, | ||
tpl.templateRange[0] | ||
); | ||
const allNodes = []; | ||
@@ -227,2 +258,3 @@ glimmer.traverse(ast, { | ||
comments.push(node); | ||
currentComments.push(node); | ||
} | ||
@@ -272,13 +304,8 @@ if (node.type === 'TextNode') { | ||
let start = n.range[0]; | ||
let codeSlice = code.slice(...n.range); | ||
let codeSlice = sliceByteRange(code, ...n.range); | ||
for (const part of n.tag.split('.')) { | ||
let pattern = `\\b${part}\\b`; | ||
if (part.startsWith(':')) { | ||
pattern = `${part}\\b`; | ||
} | ||
const regex = new RegExp(pattern); | ||
const match = codeSlice.match(regex); | ||
const range = [start + match.index, 0]; | ||
const idx = codeSlice.indexOf(part); | ||
const range = [start + idx, 0]; | ||
range[1] = range[0] + part.length; | ||
codeSlice = code.slice(range[1], n.range[1]); | ||
codeSlice = sliceByteRange(code, range[1], n.range[1]); | ||
start = range[1]; | ||
@@ -303,4 +330,7 @@ n.parts.push({ | ||
if ('blockParams' in n && n.parent) { | ||
let part = code.slice(...n.parent.range); | ||
let start = n.parent.range[0]; | ||
// for blocks {{x as |b|}} the block range does not contain the block params... | ||
// for element tag it does <x as b /> | ||
const blockRange = n.type === 'Block' ? n.parent.range : n.range; | ||
let part = sliceByteRange(code, ...blockRange); | ||
let start = blockRange[0]; | ||
let idx = part.indexOf('|') + 1; | ||
@@ -332,6 +362,8 @@ start += idx; | ||
// ast should not contain comment nodes | ||
for (const comment of comments) { | ||
for (const comment of currentComments) { | ||
const parentBody = comment.parent.body || comment.parent.children; | ||
const idx = parentBody.indexOf(comment); | ||
parentBody.splice(idx, 1); | ||
if (idx >= 0) { | ||
parentBody.splice(idx, 1); | ||
} | ||
// comment type can be a block comment or a line comment | ||
@@ -410,4 +442,4 @@ // mark comments as always block comment, this works for eslint in all cases | ||
(t) => | ||
t.templateRange[0] === range[0] && | ||
(t.templateRange[1] === range[1] || t.templateRange[1] === range[1] + 1) | ||
t.utf16Range[0] === range[0] && | ||
(t.utf16Range[1] === range[1] || t.utf16Range[1] === range[1] + 1) | ||
); | ||
@@ -450,2 +482,3 @@ if (!template) { | ||
!n.name.startsWith(':') && | ||
!n.name.startsWith('@') && | ||
scope && | ||
@@ -483,3 +516,3 @@ (variable || | ||
const replaceRange = function replaceRange(s, start, end, substitute) { | ||
return s.slice(0, start) + substitute + s.slice(end); | ||
return sliceByteRange(s, 0, start) + substitute + sliceByteRange(s, end); | ||
}; | ||
@@ -518,10 +551,11 @@ module.exports.replaceRange = replaceRange; | ||
for (const tplInfo of result.reverse()) { | ||
const lineBreaks = [...tplInfo.contents].reduce( | ||
(prev, curr) => prev + (DocumentLines.isLineBreak(curr.codePointAt(0)) ? 1 : 0), | ||
const backticks = [...tplInfo.contents].reduce( | ||
(prev, curr) => (prev + (curr.codePointAt(0) === '`') ? 1 : 0), | ||
0 | ||
); | ||
const content = tplInfo.contents.replace(/`/g, '\\`'); | ||
if (tplInfo.type === 'class-member') { | ||
const tplLength = tplInfo.range.end - tplInfo.range.start; | ||
const spaces = tplLength - 'static{`'.length - '`}'.length - lineBreaks; | ||
const total = ' '.repeat(spaces) + '\n'.repeat(lineBreaks); | ||
const spaces = tplLength - byteLength(content) - 'static{`'.length - '`}'.length - backticks; | ||
const total = content + ' '.repeat(spaces); | ||
const replacementCode = `static{\`${total}\`}`; | ||
@@ -531,4 +565,4 @@ jsCode = replaceRange(jsCode, tplInfo.range.start, tplInfo.range.end, replacementCode); | ||
const tplLength = tplInfo.range.end - tplInfo.range.start; | ||
const spaces = tplLength - '""`'.length - '`'.length - lineBreaks; | ||
const total = ' '.repeat(spaces) + '\n'.repeat(lineBreaks); | ||
const spaces = tplLength - byteLength(content) - '""`'.length - '`'.length - backticks; | ||
const total = content + ' '.repeat(spaces); | ||
const replacementCode = `""\`${total}\``; | ||
@@ -535,0 +569,0 @@ jsCode = replaceRange(jsCode, tplInfo.range.start, tplInfo.range.end, replacementCode); |
29748
825