Skip to content

Commit 9cf2243

Browse files
authored
Fix false negatives in <i18n> block without <template> in no-unused-keys rule. (#111)
1 parent 5281fa4 commit 9cf2243

File tree

2 files changed

+88
-8
lines changed

2 files changed

+88
-8
lines changed

lib/utils/parsers/index.ts

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,46 @@ export interface YAMLParsed extends Parsed<YAMLAST.YAMLNode> {
5656
ast: YAMLAST.YAMLProgram
5757
}
5858

59+
function hasEndTag(
60+
element: VAST.VElement
61+
): element is VAST.VElement & { endTag: VAST.VEndTag } {
62+
return !!element.endTag
63+
}
64+
65+
function getSourceCodeString(
66+
context: RuleContext,
67+
i18nBlock: VAST.VElement & { endTag: VAST.VEndTag }
68+
): string {
69+
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
70+
const tokens = tokenStore.getTokensBetween(
71+
i18nBlock.startTag,
72+
i18nBlock.endTag
73+
)
74+
if (
75+
tokens.length ||
76+
i18nBlock.startTag.range[1] === i18nBlock.endTag.range[0]
77+
) {
78+
return tokens.map(t => t.value).join('')
79+
}
80+
// without <template></template>
81+
const df = context.parserServices.getDocumentFragment?.()
82+
if (!df) {
83+
return ''
84+
}
85+
const start = i18nBlock.startTag.range[1]
86+
const end = i18nBlock.endTag.range[0]
87+
let sourceCode = ''
88+
for (const token of df.tokens) {
89+
if (start <= token.range[0] && token.range[1] <= end) {
90+
sourceCode += token.value
91+
}
92+
if (end <= token.range[0]) {
93+
break
94+
}
95+
}
96+
return sourceCode
97+
}
98+
5999
/**
60100
* @param {RuleContext} context
61101
* @param {VElement} i18nBlock
@@ -68,19 +108,14 @@ function parseInI18nBlock<P extends JSONAST.JSONProgram | YAMLAST.YAMLProgram>(
68108
option: unknown
69109
) => { ast: P; visitorKeys: VisitorKeys }
70110
) {
71-
if (!i18nBlock.endTag) {
111+
if (!hasEndTag(i18nBlock)) {
72112
return null
73113
}
74-
const offsetIndex = i18nBlock.startTag.range[1]
75-
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
76-
const tokens = tokenStore.getTokensBetween(
77-
i18nBlock.startTag,
78-
i18nBlock.endTag
79-
)
80-
const sourceString = tokens.map(t => t.value).join('')
114+
const sourceString = getSourceCodeString(context, i18nBlock)
81115
if (!sourceString.trim()) {
82116
return null
83117
}
118+
const offsetIndex = i18nBlock.startTag.range[1]
84119
const sourceCode = context.getSourceCode()
85120
const locationFixer = new LocationFixer(
86121
sourceCode,

tests/lib/rules/no-unused-keys.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,51 @@ ${' '.repeat(6)}
872872
"unused 'unuse' key",
873873
"unused 'array-unuse[0]' key"
874874
]
875+
},
876+
{
877+
// without <template>
878+
filename: 'test.vue',
879+
code: `
880+
<i18n lang="yaml" locale="en">
881+
test: Test
882+
</i18n>
883+
<script>
884+
// without <template>
885+
export default {
886+
render (createElement) {}
887+
}
888+
</script>`,
889+
options: [{ enableFix: true }],
890+
output: `
891+
<i18n lang="yaml" locale="en">
892+
{}
893+
</i18n>
894+
<script>
895+
// without <template>
896+
export default {
897+
render (createElement) {}
898+
}
899+
</script>`,
900+
errors: [
901+
{
902+
message: "unused 'test' key",
903+
suggestions: [
904+
{
905+
desc: "Remove the 'test' key.",
906+
output: `
907+
<i18n lang="yaml" locale="en">
908+
{}
909+
</i18n>
910+
<script>
911+
// without <template>
912+
export default {
913+
render (createElement) {}
914+
}
915+
</script>`
916+
}
917+
]
918+
}
919+
]
875920
}
876921
]
877922
})

0 commit comments

Comments
 (0)