ember-eslint-parser 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/parser/transforms.js +59 -25
package/package.json
CHANGED
package/src/parser/transforms.js
CHANGED
|
@@ -6,6 +6,31 @@ const TypescriptScope = require('@typescript-eslint/scope-manager');
|
|
|
6
6
|
const { Reference, Scope, Variable, Definition } = require('eslint-scope');
|
|
7
7
|
const htmlTags = require('html-tags');
|
|
8
8
|
|
|
9
|
+
const BufferMap = new Map();
|
|
10
|
+
|
|
11
|
+
function getBuffer(str) {
|
|
12
|
+
let buf = BufferMap.get(str);
|
|
13
|
+
if (!buf) {
|
|
14
|
+
buf = Buffer.from(str);
|
|
15
|
+
BufferMap.set(str, buf);
|
|
16
|
+
}
|
|
17
|
+
return buf;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function sliceByteRange(str, a, b) {
|
|
21
|
+
const buf = getBuffer(str);
|
|
22
|
+
return buf.slice(a, b).toString();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function byteToCharIndex(str, byteOffset) {
|
|
26
|
+
const buf = getBuffer(str);
|
|
27
|
+
return buf.slice(0, byteOffset + 1).toString().length - 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function byteLength(str) {
|
|
31
|
+
return getBuffer(str).length;
|
|
32
|
+
}
|
|
33
|
+
|
|
9
34
|
/**
|
|
10
35
|
* finds the nearest node scope
|
|
11
36
|
* @param scopeManager
|
|
@@ -202,17 +227,23 @@ module.exports.preprocessGlimmerTemplates = function preprocessGlimmerTemplates(
|
|
|
202
227
|
const templateInfos = info.templateInfos.map((r) => ({
|
|
203
228
|
range: [r.contentRange.start, r.contentRange.end],
|
|
204
229
|
templateRange: [r.range.start, r.range.end],
|
|
230
|
+
utf16Range: [byteToCharIndex(code, r.range.start), byteToCharIndex(code, r.range.end)],
|
|
205
231
|
}));
|
|
206
232
|
const templateVisitorKeys = {};
|
|
207
233
|
const codeLines = new DocumentLines(code);
|
|
208
234
|
const comments = [];
|
|
209
|
-
const textNodes = [];
|
|
210
235
|
for (const tpl of templateInfos) {
|
|
236
|
+
const currentComments = [];
|
|
237
|
+
const textNodes = [];
|
|
211
238
|
const range = tpl.range;
|
|
212
|
-
const template = code
|
|
239
|
+
const template = sliceByteRange(code, ...range);
|
|
213
240
|
const docLines = new DocumentLines(template);
|
|
214
241
|
const ast = glimmer.preprocess(template, { mode: 'codemod' });
|
|
215
|
-
ast.tokens = tokenize(
|
|
242
|
+
ast.tokens = tokenize(
|
|
243
|
+
sliceByteRange(code, ...tpl.templateRange),
|
|
244
|
+
codeLines,
|
|
245
|
+
tpl.templateRange[0]
|
|
246
|
+
);
|
|
216
247
|
const allNodes = [];
|
|
217
248
|
glimmer.traverse(ast, {
|
|
218
249
|
All(node, path) {
|
|
@@ -221,6 +252,7 @@ module.exports.preprocessGlimmerTemplates = function preprocessGlimmerTemplates(
|
|
|
221
252
|
allNodes.push(node);
|
|
222
253
|
if (node.type === 'CommentStatement' || node.type === 'MustacheCommentStatement') {
|
|
223
254
|
comments.push(node);
|
|
255
|
+
currentComments.push(node);
|
|
224
256
|
}
|
|
225
257
|
if (node.type === 'TextNode') {
|
|
226
258
|
n.value = node.chars;
|
|
@@ -265,17 +297,12 @@ module.exports.preprocessGlimmerTemplates = function preprocessGlimmerTemplates(
|
|
|
265
297
|
n.name = n.tag;
|
|
266
298
|
n.parts = [];
|
|
267
299
|
let start = n.range[0];
|
|
268
|
-
let codeSlice = code
|
|
300
|
+
let codeSlice = sliceByteRange(code, ...n.range);
|
|
269
301
|
for (const part of n.tag.split('.')) {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
pattern = `${part}\\b`;
|
|
273
|
-
}
|
|
274
|
-
const regex = new RegExp(pattern);
|
|
275
|
-
const match = codeSlice.match(regex);
|
|
276
|
-
const range = [start + match.index, 0];
|
|
302
|
+
const idx = codeSlice.indexOf(part);
|
|
303
|
+
const range = [start + idx, 0];
|
|
277
304
|
range[1] = range[0] + part.length;
|
|
278
|
-
codeSlice = code
|
|
305
|
+
codeSlice = sliceByteRange(code, range[1], n.range[1]);
|
|
279
306
|
start = range[1];
|
|
280
307
|
n.parts.push({
|
|
281
308
|
type: 'GlimmerElementNodePart',
|
|
@@ -295,8 +322,11 @@ module.exports.preprocessGlimmerTemplates = function preprocessGlimmerTemplates(
|
|
|
295
322
|
n.params = [];
|
|
296
323
|
}
|
|
297
324
|
if ('blockParams' in n && n.parent) {
|
|
298
|
-
|
|
299
|
-
|
|
325
|
+
// for blocks {{x as |b|}} the block range does not contain the block params...
|
|
326
|
+
// for element tag it does <x as b />
|
|
327
|
+
const blockRange = n.type === 'Block' ? n.parent.range : n.range;
|
|
328
|
+
let part = sliceByteRange(code, ...blockRange);
|
|
329
|
+
let start = blockRange[0];
|
|
300
330
|
let idx = part.indexOf('|') + 1;
|
|
301
331
|
start += idx;
|
|
302
332
|
part = part.slice(idx, -1);
|
|
@@ -323,10 +353,12 @@ module.exports.preprocessGlimmerTemplates = function preprocessGlimmerTemplates(
|
|
|
323
353
|
allNodeTypes.add(n.type);
|
|
324
354
|
}
|
|
325
355
|
// ast should not contain comment nodes
|
|
326
|
-
for (const comment of
|
|
356
|
+
for (const comment of currentComments) {
|
|
327
357
|
const parentBody = comment.parent.body || comment.parent.children;
|
|
328
358
|
const idx = parentBody.indexOf(comment);
|
|
329
|
-
|
|
359
|
+
if (idx >= 0) {
|
|
360
|
+
parentBody.splice(idx, 1);
|
|
361
|
+
}
|
|
330
362
|
// comment type can be a block comment or a line comment
|
|
331
363
|
// mark comments as always block comment, this works for eslint in all cases
|
|
332
364
|
comment.type = 'Block';
|
|
@@ -400,8 +432,8 @@ module.exports.convertAst = function convertAst(result, preprocessedResult, visi
|
|
|
400
432
|
|
|
401
433
|
const template = templateInfos.find(
|
|
402
434
|
(t) =>
|
|
403
|
-
t.
|
|
404
|
-
(t.
|
|
435
|
+
t.utf16Range[0] === range[0] &&
|
|
436
|
+
(t.utf16Range[1] === range[1] || t.utf16Range[1] === range[1] + 1)
|
|
405
437
|
);
|
|
406
438
|
if (!template) {
|
|
407
439
|
return null;
|
|
@@ -439,6 +471,7 @@ module.exports.convertAst = function convertAst(result, preprocessedResult, visi
|
|
|
439
471
|
if (
|
|
440
472
|
n.name !== 'this' &&
|
|
441
473
|
!n.name.startsWith(':') &&
|
|
474
|
+
!n.name.startsWith('@') &&
|
|
442
475
|
scope &&
|
|
443
476
|
(variable ||
|
|
444
477
|
isUpperCase(n.name[0]) ||
|
|
@@ -471,7 +504,7 @@ module.exports.convertAst = function convertAst(result, preprocessedResult, visi
|
|
|
471
504
|
};
|
|
472
505
|
|
|
473
506
|
const replaceRange = function replaceRange(s, start, end, substitute) {
|
|
474
|
-
return s
|
|
507
|
+
return sliceByteRange(s, 0, start) + substitute + sliceByteRange(s, end);
|
|
475
508
|
};
|
|
476
509
|
module.exports.replaceRange = replaceRange;
|
|
477
510
|
|
|
@@ -505,20 +538,21 @@ module.exports.transformForLint = function transformForLint(code) {
|
|
|
505
538
|
*/
|
|
506
539
|
const result = processor.parse(code);
|
|
507
540
|
for (const tplInfo of result.reverse()) {
|
|
508
|
-
const
|
|
509
|
-
(prev, curr) => prev + (
|
|
541
|
+
const backticks = [...tplInfo.contents].reduce(
|
|
542
|
+
(prev, curr) => (prev + (curr.codePointAt(0) === '`') ? 1 : 0),
|
|
510
543
|
0
|
|
511
544
|
);
|
|
545
|
+
const content = tplInfo.contents.replace(/`/g, '\\`');
|
|
512
546
|
if (tplInfo.type === 'class-member') {
|
|
513
547
|
const tplLength = tplInfo.range.end - tplInfo.range.start;
|
|
514
|
-
const spaces = tplLength - 'static{`'.length - '`}'.length -
|
|
515
|
-
const total =
|
|
548
|
+
const spaces = tplLength - byteLength(content) - 'static{`'.length - '`}'.length - backticks;
|
|
549
|
+
const total = content + ' '.repeat(spaces);
|
|
516
550
|
const replacementCode = `static{\`${total}\`}`;
|
|
517
551
|
jsCode = replaceRange(jsCode, tplInfo.range.start, tplInfo.range.end, replacementCode);
|
|
518
552
|
} else {
|
|
519
553
|
const tplLength = tplInfo.range.end - tplInfo.range.start;
|
|
520
|
-
const spaces = tplLength - '""`'.length - '`'.length -
|
|
521
|
-
const total =
|
|
554
|
+
const spaces = tplLength - byteLength(content) - '""`'.length - '`'.length - backticks;
|
|
555
|
+
const total = content + ' '.repeat(spaces);
|
|
522
556
|
const replacementCode = `""\`${total}\``;
|
|
523
557
|
jsCode = replaceRange(jsCode, tplInfo.range.start, tplInfo.range.end, replacementCode);
|
|
524
558
|
}
|