Skip to content

Commit

Permalink
Fix false negatives for member expression in no-dynamic-keys rule (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi authored Jan 4, 2021
1 parent e180387 commit 689f1b9
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 10 deletions.
58 changes: 48 additions & 10 deletions lib/rules/no-dynamic-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,53 @@ import { defineTemplateBodyVisitor } from '../utils/index'
import type { RuleContext, RuleListener } from '../types'
import type { AST as VAST } from 'vue-eslint-parser'

function isStatic(
node:
| VAST.ESLintExpression
| VAST.ESLintSpreadElement
| VAST.VFilterSequenceExpression
| VAST.VForExpression
| VAST.VOnExpression
| VAST.VSlotScopeExpression
): boolean {
if (node.type === 'Literal') {
return true
}
if (node.type === 'TemplateLiteral' && node.expressions.length === 0) {
return true
}
return false
}

function getNodeName(context: RuleContext, node: VAST.Node): string {
if (node.type === 'Identifier') {
return node.name
}
const sourceCode = context.getSourceCode()
if (
sourceCode.ast.range[0] <= node.range[0] &&
node.range[1] <= sourceCode.ast.range[1]
) {
return sourceCode
.getTokens(node)
.map(t => t.value)
.join('')
}
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
return tokenStore
.getTokens(node)
.map(t => t.value)
.join('')
}

function checkDirective(context: RuleContext, node: VAST.VDirective) {
if (
node.value &&
node.value.type === 'VExpressionContainer' &&
node.value.expression &&
node.value.expression.type === 'Identifier'
!isStatic(node.value.expression)
) {
const name = node.value.expression.name
const name = getNodeName(context, node.value.expression)
context.report({
node,
message: `'${name}' dynamic key is used'`
Expand All @@ -21,19 +60,18 @@ function checkDirective(context: RuleContext, node: VAST.VDirective) {
}

function checkComponent(context: RuleContext, node: VAST.VDirectiveKey) {
const parent: VAST.VDirective = node.parent as never // typebug?
if (
node.name.type === 'VIdentifier' &&
node.name.name === 'bind' &&
node.argument &&
node.argument.type === 'VIdentifier' &&
node.argument.name === 'path' &&
parent.value &&
parent.value.type === 'VExpressionContainer' &&
parent.value.expression &&
parent.value.expression.type === 'Identifier'
node.parent.value &&
node.parent.value.type === 'VExpressionContainer' &&
node.parent.value.expression &&
!isStatic(node.parent.value.expression)
) {
const name = parent.value.expression.name
const name = getNodeName(context, node.parent.value.expression)
context.report({
node,
message: `'${name}' dynamic key is used'`
Expand Down Expand Up @@ -61,8 +99,8 @@ function checkCallExpression(
}

const [keyNode] = node.arguments
if (keyNode.type === 'Identifier') {
const name = keyNode.name
if (!isStatic(keyNode)) {
const name = getNodeName(context, keyNode)
context.report({
node,
message: `'${name}' dynamic key is used'`
Expand Down
45 changes: 45 additions & 0 deletions tests/lib/rules/no-dynamic-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ tester.run('no-dynamic-keys', rule as never, {
code: `<template>
<p v-t="'hello'"></p>
</template>`
},
{
code: `
<template>
<p>{{ $t(\`foo\`) }}</p>
<i18n :path="\`foo\`"/>
<p v-t="\`foo\`"></p>
</template>
<script>
i18n.t(\`foo\`)
</script>`
}
],

Expand Down Expand Up @@ -82,6 +93,40 @@ tester.run('no-dynamic-keys', rule as never, {
<p v-t="missing"></p>
</template>`,
errors: [`'missing' dynamic key is used'`]
},
{
code: `
<template>
<p>{{ $t(foo.dynamic) }}</p>
<i18n :path="foo.dynamic"/>
<p v-t="foo.dynamic"></p>
</template>
<script>
i18n.t(foo.dynamic)
</script>`,
errors: [
"'foo.dynamic' dynamic key is used'",
"'foo.dynamic' dynamic key is used'",
"'foo.dynamic' dynamic key is used'",
"'foo.dynamic' dynamic key is used'"
]
},
{
code: `
<template>
<p>{{ $t(foo()) }}</p>
<i18n :path="foo()"/>
<p v-t="foo()"></p>
</template>
<script>
i18n.t(foo())
</script>`,
errors: [
"'foo()' dynamic key is used'",
"'foo()' dynamic key is used'",
"'foo()' dynamic key is used'",
"'foo()' dynamic key is used'"
]
}
]
})

0 comments on commit 689f1b9

Please sign in to comment.