ember-eslint-parser 0.2.2 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-eslint-parser",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "repository": {
@@ -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.slice(...range);
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(code.slice(...tpl.templateRange), codeLines, tpl.templateRange[0]);
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.slice(...n.range);
300
+ let codeSlice = sliceByteRange(code, ...n.range);
269
301
  for (const part of n.tag.split('.')) {
270
- let pattern = `\\b${part}\\b`;
271
- if (part.startsWith(':')) {
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.slice(range[1], n.range[1]);
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
- let part = code.slice(...n.parent.range);
299
- let start = n.parent.range[0];
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 comments) {
356
+ for (const comment of currentComments) {
327
357
  const parentBody = comment.parent.body || comment.parent.children;
328
358
  const idx = parentBody.indexOf(comment);
329
- parentBody.splice(idx, 1);
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.templateRange[0] === range[0] &&
404
- (t.templateRange[1] === range[1] || t.templateRange[1] === range[1] + 1)
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;
@@ -437,7 +469,9 @@ module.exports.convertAst = function convertAst(result, preprocessedResult, visi
437
469
  * it's NOT a standard html tag, it should have a referenced variable
438
470
  */
439
471
  if (
472
+ n.name !== 'this' &&
440
473
  !n.name.startsWith(':') &&
474
+ !n.name.startsWith('@') &&
441
475
  scope &&
442
476
  (variable ||
443
477
  isUpperCase(n.name[0]) ||
@@ -470,7 +504,7 @@ module.exports.convertAst = function convertAst(result, preprocessedResult, visi
470
504
  };
471
505
 
472
506
  const replaceRange = function replaceRange(s, start, end, substitute) {
473
- return s.slice(0, start) + substitute + s.slice(end);
507
+ return sliceByteRange(s, 0, start) + substitute + sliceByteRange(s, end);
474
508
  };
475
509
  module.exports.replaceRange = replaceRange;
476
510
 
@@ -504,20 +538,21 @@ module.exports.transformForLint = function transformForLint(code) {
504
538
  */
505
539
  const result = processor.parse(code);
506
540
  for (const tplInfo of result.reverse()) {
507
- const lineBreaks = [...tplInfo.contents].reduce(
508
- (prev, curr) => prev + (DocumentLines.isLineBreak(curr.codePointAt(0)) ? 1 : 0),
541
+ const backticks = [...tplInfo.contents].reduce(
542
+ (prev, curr) => (prev + (curr.codePointAt(0) === '`') ? 1 : 0),
509
543
  0
510
544
  );
545
+ const content = tplInfo.contents.replace(/`/g, '\\`');
511
546
  if (tplInfo.type === 'class-member') {
512
547
  const tplLength = tplInfo.range.end - tplInfo.range.start;
513
- const spaces = tplLength - 'static{`'.length - '`}'.length - lineBreaks;
514
- const total = ' '.repeat(spaces) + '\n'.repeat(lineBreaks);
548
+ const spaces = tplLength - byteLength(content) - 'static{`'.length - '`}'.length - backticks;
549
+ const total = content + ' '.repeat(spaces);
515
550
  const replacementCode = `static{\`${total}\`}`;
516
551
  jsCode = replaceRange(jsCode, tplInfo.range.start, tplInfo.range.end, replacementCode);
517
552
  } else {
518
553
  const tplLength = tplInfo.range.end - tplInfo.range.start;
519
- const spaces = tplLength - '""`'.length - '`'.length - lineBreaks;
520
- const total = ' '.repeat(spaces) + '\n'.repeat(lineBreaks);
554
+ const spaces = tplLength - byteLength(content) - '""`'.length - '`'.length - backticks;
555
+ const total = content + ' '.repeat(spaces);
521
556
  const replacementCode = `""\`${total}\``;
522
557
  jsCode = replaceRange(jsCode, tplInfo.range.start, tplInfo.range.end, replacementCode);
523
558
  }