Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/rules/no-unused-keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ i18n.t('hi')
"src": "./src",
"extensions": [".js", ".vue"],
"ignores": [],
"enableFix": false
"enableFix": false,
"callExpression": "^(\\$t|t|\\$tc|tc)$"
}
]
}
Expand All @@ -174,6 +175,7 @@ i18n.t('hi')
- `extensions`: an array to allow specified lintable target file extension. If you don't set any options, it set to `.js` and `.vue` as default.
- `ignores`: An array of key names and patterns to exclude from the check. If you want to specify a pattern, specify a string such as `/pattern/`.
- `enableFix`: if `true`, enable automatically remove unused keys on `eslint --fix`. If you don't set any options, it set to `false` as default. (This is an experimental feature.)
- `callExpression`: A regular expression used to identify translation function calls.

## :couple: Related Rules

Expand Down
9 changes: 8 additions & 1 deletion lib/rules/no-unused-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ function create(context: RuleContext): RuleListener {
const options = (context.options && context.options[0]) || {}
const enableFix = options.enableFix
const ignores = ((options.ignores || []) as string[]).map(toRegExp)
const callExpression =
(options.callExpression && new RegExp(options.callExpression)) ||
/^(\$t|t|\$tc|tc)$/

function createVerifyContext<N extends JSONAST.JSONNode | YAMLAST.YAMLNode>(
usedKeys: UsedKeys,
Expand Down Expand Up @@ -512,7 +515,8 @@ function create(context: RuleContext): RuleListener {
const localeMessages = getLocaleMessages(context)
const usedLocaleMessageKeys = collectKeysFromAST(
sourceCode.ast as VAST.ESLintProgram,
sourceCode.visitorKeys
sourceCode.visitorKeys,
callExpression
)
const targetLocaleMessage = localeMessages.findBlockLocaleMessage(
ctx.parserServices.customBlock
Expand Down Expand Up @@ -601,6 +605,9 @@ export = createRule({
},
enableFix: {
type: 'boolean'
},
callExpression: {
type: 'string'
}
},
additionalProperties: false
Expand Down
12 changes: 8 additions & 4 deletions lib/utils/collect-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ const debug = debugBuilder('eslint-plugin-vue-i18n:collect-keys')
*
* @param {CallExpression} node
*/
function getKeyFromCallExpression(node: VAST.ESLintCallExpression) {
function getKeyFromCallExpression(
node: VAST.ESLintCallExpression,
callExpression?: RegExp
) {
const funcName =
(node.callee.type === 'MemberExpression' &&
node.callee.property.type === 'Identifier' &&
Expand All @@ -29,7 +32,7 @@ function getKeyFromCallExpression(node: VAST.ESLintCallExpression) {
''

if (
!/^(\$t|t|\$tc|tc)$/.test(funcName) ||
!(callExpression ?? /^(\$t|t|\$tc|tc)$/).test(funcName) ||
!node.arguments ||
!node.arguments.length
) {
Expand Down Expand Up @@ -121,7 +124,8 @@ function collectKeyResourcesFromFiles(fileNames: string[], cwd: string) {
*/
export function collectKeysFromAST(
node: VAST.ESLintProgram,
visitorKeys?: VisitorKeys
visitorKeys?: VisitorKeys,
callExpression?: RegExp
): string[] {
debug('collectKeysFromAST')

Expand Down Expand Up @@ -168,7 +172,7 @@ export function collectKeysFromAST(
}
} else if (node.type === 'CallExpression') {
debug('CallExpression handling ...')
const key = getKeyFromCallExpression(node)
const key = getKeyFromCallExpression(node, callExpression)
if (key) {
results.add(String(key))
}
Expand Down
21 changes: 21 additions & 0 deletions tests/lib/rules/no-unused-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,27 @@ new RuleTester({
}
}
</script>`
},
{
filename: 'test.vue',
code: `
<i18n locale="en">
{
"foo": "foo",
"bar": {
"nest": "nest",
},
}
</i18n>
<script>
export default {
created () {
this.customFn1('foo')
this.customFn2('bar.nest')
}
}
</script>`,
options: [{ callExpression: 'customFn\\d' }]
}
],
invalid: [
Expand Down