Skip to content

Commit

Permalink
no-instanceof-array: Support Vue SFC (#1410)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed Jul 12, 2021
1 parent 33aa97d commit 3b22917
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 10 deletions.
6 changes: 3 additions & 3 deletions rules/fix/replace-node-or-token-and-spaces-before.js
@@ -1,11 +1,11 @@
'use strict';
const {getParentheses} = require('../utils/parentheses.js');

function * replaceNodeOrTokenAndSpacesBefore(nodeOrToken, replacement, fixer, sourceCode) {
const tokens = getParentheses(nodeOrToken, sourceCode);
function * replaceNodeOrTokenAndSpacesBefore(nodeOrToken, replacement, fixer, sourceCode, tokenStore = sourceCode) {
const tokens = getParentheses(nodeOrToken, tokenStore);

for (const token of tokens) {
yield * replaceNodeOrTokenAndSpacesBefore(token, '', fixer, sourceCode);
yield * replaceNodeOrTokenAndSpacesBefore(token, '', fixer, sourceCode, tokenStore);
}

let [start, end] = nodeOrToken.range;
Expand Down
16 changes: 11 additions & 5 deletions rules/no-instanceof-array.js
@@ -1,4 +1,5 @@
'use strict';
const {checkVueTemplate} = require('./utils/rule.js');
const {getParenthesizedRange} = require('./utils/parentheses.js');
const {replaceNodeOrTokenAndSpacesBefore} = require('./fix/index.js');

Expand All @@ -21,27 +22,32 @@ const create = context => {
return {
[selector](node) {
const {left, right} = node;
const instanceofToken = sourceCode.getTokenAfter(left, isInstanceofToken);
let tokenStore = sourceCode;
let instanceofToken = tokenStore.getTokenAfter(left, isInstanceofToken);
if (!instanceofToken && context.parserServices.getTemplateBodyTokenStore) {
tokenStore = context.parserServices.getTemplateBodyTokenStore();
instanceofToken = tokenStore.getTokenAfter(left, isInstanceofToken);
}

return {
node: instanceofToken,
messageId: MESSAGE_ID,
/** @param {import('eslint').Rule.RuleFixer} fixer */
* fix(fixer) {
const range = getParenthesizedRange(left, sourceCode);
const range = getParenthesizedRange(left, tokenStore);
yield fixer.insertTextBeforeRange(range, 'Array.isArray(');
yield fixer.insertTextAfterRange(range, ')');

yield * replaceNodeOrTokenAndSpacesBefore(instanceofToken, '', fixer, sourceCode);
yield * replaceNodeOrTokenAndSpacesBefore(right, '', fixer, sourceCode);
yield * replaceNodeOrTokenAndSpacesBefore(instanceofToken, '', fixer, sourceCode, tokenStore);
yield * replaceNodeOrTokenAndSpacesBefore(right, '', fixer, sourceCode, tokenStore);
}
};
}
};
};

module.exports = {
create,
create: checkVueTemplate(create),
meta: {
type: 'suggestion',
docs: {
Expand Down
12 changes: 10 additions & 2 deletions test/no-instanceof-array.mjs
@@ -1,5 +1,5 @@
import outdent from 'outdent';
import {getTester} from './utils/test.mjs';
import {getTester, parsers} from './utils/test.mjs';

const {test} = getTester(import.meta);

Expand Down Expand Up @@ -56,6 +56,14 @@ test.snapshot({
)
// comment
`
`,
...[
'<template><div v-if="array instanceof Array" v-for="element of array"></div></template>',
'<template><div v-if="(( (( array )) instanceof (( Array )) ))" v-for="element of array"></div></template>',
'<template><div>{{(( (( array )) instanceof (( Array )) )) ? array.join(" | ") : array}}</div></template>',
'<script>const foo = array instanceof Array</script>',
'<script>const foo = (( (( array )) instanceof (( Array )) ))</script>'
].map(code => ({code, parser: parsers.vue}))
]
});

80 changes: 80 additions & 0 deletions test/snapshots/no-instanceof-array.mjs.md
Expand Up @@ -226,3 +226,83 @@ Generated by [AVA](https://avajs.dev).
33 |␊
34 | // comment␊
`

## Invalid #9
1 | <template><div v-if="array instanceof Array" v-for="element of array"></div></template>

> Output
`␊
1 | <template><div v-if="Array.isArray(array)" v-for="element of array"></div></template>␊
`

> Error 1/1
`␊
> 1 | <template><div v-if="array instanceof Array" v-for="element of array"></div></template>␊
| ^^^^^^^^^^ Use \`Array.isArray()\` instead of \`instanceof Array\`.␊
`

## Invalid #10
1 | <template><div v-if="(( (( array )) instanceof (( Array )) ))" v-for="element of array"></div></template>

> Output
`␊
1 | <template><div v-if="(( Array.isArray((( array ))) ))" v-for="element of array"></div></template>␊
`

> Error 1/1
`␊
> 1 | <template><div v-if="(( (( array )) instanceof (( Array )) ))" v-for="element of array"></div></template>␊
| ^^^^^^^^^^ Use \`Array.isArray()\` instead of \`instanceof Array\`.␊
`

## Invalid #11
1 | <template><div>{{(( (( array )) instanceof (( Array )) )) ? array.join(" | ") : array}}</div></template>

> Output
`␊
1 | <template><div>{{(( Array.isArray((( array ))) )) ? array.join(" | ") : array}}</div></template>␊
`

> Error 1/1
`␊
> 1 | <template><div>{{(( (( array )) instanceof (( Array )) )) ? array.join(" | ") : array}}</div></template>␊
| ^^^^^^^^^^ Use \`Array.isArray()\` instead of \`instanceof Array\`.␊
`

## Invalid #12
1 | <script>const foo = array instanceof Array</script>

> Output
`␊
1 | <script>const foo = Array.isArray(array)</script>␊
`

> Error 1/1
`␊
> 1 | <script>const foo = array instanceof Array</script>␊
| ^^^^^^^^^^ Use \`Array.isArray()\` instead of \`instanceof Array\`.␊
`

## Invalid #13
1 | <script>const foo = (( (( array )) instanceof (( Array )) ))</script>

> Output
`␊
1 | <script>const foo = (( Array.isArray((( array ))) ))</script>␊
`

> Error 1/1
`␊
> 1 | <script>const foo = (( (( array )) instanceof (( Array )) ))</script>␊
| ^^^^^^^^^^ Use \`Array.isArray()\` instead of \`instanceof Array\`.␊
`
Binary file modified test/snapshots/no-instanceof-array.mjs.snap
Binary file not shown.

0 comments on commit 3b22917

Please sign in to comment.