Skip to content

Commit

Permalink
feat: add support for eslint v9 (#463)
Browse files Browse the repository at this point in the history
* feat: add support for eslint v9

* Create shiny-colts-search.md

* fix

* format
  • Loading branch information
ota-meshi committed Jan 17, 2024
1 parent 7042275 commit a488f15
Show file tree
Hide file tree
Showing 48 changed files with 424 additions and 268 deletions.
5 changes: 5 additions & 0 deletions .changeset/shiny-colts-search.md
@@ -0,0 +1,5 @@
---
"@intlify/eslint-plugin-vue-i18n": minor
---

feat: add support for eslint v9
37 changes: 36 additions & 1 deletion .eslintrc.cjs
Expand Up @@ -20,7 +20,42 @@ module.exports = {
rules: {
'object-shorthand': 'error',
'no-debugger': 'error',
'vue/multi-word-component-names': 'off'
'vue/multi-word-component-names': 'off',

'prefer-template': 'error',
'no-restricted-properties': [
'error',
{
object: 'context',
property: 'getSourceCode',
message: 'Use lib/utils/compat.ts'
},
{
object: 'context',
property: 'getFilename',
message: 'Use lib/utils/compat.ts'
},
{
object: 'context',
property: 'getPhysicalFilename',
message: 'Use lib/utils/compat.ts'
},
{
object: 'context',
property: 'getCwd',
message: 'Use lib/utils/compat.ts'
},
{
object: 'context',
property: 'getScope',
message: 'Use lib/utils/compat.ts'
},
{
object: 'context',
property: 'parserServices',
message: 'Use lib/utils/compat.ts'
}
]
},
overrides: [
{
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Expand Up @@ -56,8 +56,8 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
eslint: [5, 6, 7, 8]
node: [16]
eslint: [5, 6, 7, 8, ^9.0.0-0]
node: [20]
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion docs/.vitepress/components/resource-group.vue
Expand Up @@ -14,7 +14,7 @@ export default {
return {
$resourceGroup: {
async set(fileName, code) {
Vue.set(data.fileContents, '/path/' + fileName, code)
Vue.set(data.fileContents, `/path/${fileName}`, code)
const timeSeq = ++waitSeq
await Vue.nextTick()
Expand Down
14 changes: 9 additions & 5 deletions lib/rules/key-format-style.ts
Expand Up @@ -10,6 +10,7 @@ import type { RuleContext, RuleListener } from '../types'
import { getCasingChecker } from '../utils/casing'
import type { LocaleMessage } from '../utils/locale-messages'
import { createRule } from '../utils/rule'
import { getFilename, getSourceCode } from '../utils/compat'
const debug = debugBuilder('eslint-plugin-vue-i18n:key-format-style')

const allowedCaseOptions = [
Expand All @@ -21,7 +22,8 @@ const allowedCaseOptions = [
type CaseOption = (typeof allowedCaseOptions)[number]

function create(context: RuleContext): RuleListener {
const filename = context.getFilename()
const filename = getFilename(context)
const sourceCode = getSourceCode(context)
const expectCasing: CaseOption = context.options[0] ?? 'camelCase'
const checker = getCasingChecker(expectCasing)
const allowArray: boolean = context.options[1]?.allowArray
Expand Down Expand Up @@ -115,7 +117,6 @@ function create(context: RuleContext): RuleListener {
if (cachedLoc) {
return cachedLoc
}
const sourceCode = context.getSourceCode()
return (cachedLoc = {
start: sourceCode.getLocFromIndex(offset + start),
end: sourceCode.getLocFromIndex(offset + end)
Expand Down Expand Up @@ -264,17 +265,20 @@ function create(context: RuleContext): RuleListener {
return createVisitorForYaml(targetLocaleMessage)
}
)
} else if (context.parserServices.isJSON || context.parserServices.isYAML) {
} else if (
sourceCode.parserServices.isJSON ||
sourceCode.parserServices.isYAML
) {
const localeMessages = getLocaleMessages(context)
const targetLocaleMessage = localeMessages.findExistLocaleMessage(filename)
if (!targetLocaleMessage) {
debug(`ignore ${filename} in key-format-style`)
return {}
}

if (context.parserServices.isJSON) {
if (sourceCode.parserServices.isJSON) {
return createVisitorForJson(targetLocaleMessage)
} else if (context.parserServices.isYAML) {
} else if (sourceCode.parserServices.isYAML) {
return createVisitorForYaml(targetLocaleMessage)
}
return {}
Expand Down
4 changes: 3 additions & 1 deletion lib/rules/no-deprecated-i18n-component.ts
Expand Up @@ -5,14 +5,16 @@ import { defineTemplateBodyVisitor } from '../utils/index'
import type { RuleContext, RuleListener } from '../types'
import type { AST as VAST } from 'vue-eslint-parser'
import { createRule } from '../utils/rule'
import { getSourceCode } from '../utils/compat'

function create(context: RuleContext): RuleListener {
return defineTemplateBodyVisitor(context, {
VElement(node: VAST.VElement) {
if (node.name !== 'i18n') {
return
}
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
const sourceCode = getSourceCode(context)
const tokenStore = sourceCode.parserServices.getTemplateBodyTokenStore()
const tagNameToken = tokenStore.getFirstToken(node.startTag)
context.report({
node: tagNameToken,
Expand Down
24 changes: 14 additions & 10 deletions lib/rules/no-duplicate-keys-in-locale.ts
Expand Up @@ -16,6 +16,7 @@ import type {
import { joinPath } from '../utils/key-path'
import { getCwd } from '../utils/get-cwd'
import { createRule } from '../utils/rule'
import { getFilename, getSourceCode } from '../utils/compat'
const debug = debugBuilder('eslint-plugin-vue-i18n:no-duplicate-keys-in-locale')

interface DictData {
Expand All @@ -34,13 +35,14 @@ interface PathStack {
function getMessageFilepath(fullPath: string, context: RuleContext) {
const cwd = getCwd(context)
if (fullPath.startsWith(cwd)) {
return fullPath.replace(cwd + '/', './')
return fullPath.replace(`${cwd}/`, './')
}
return fullPath
}

function create(context: RuleContext): RuleListener {
const filename = context.getFilename()
const filename = getFilename(context)
const sourceCode = getSourceCode(context)
const options = (context.options && context.options[0]) || {}
const ignoreI18nBlock = Boolean(options.ignoreI18nBlock)

Expand Down Expand Up @@ -129,7 +131,7 @@ function create(context: RuleContext): RuleListener {
}
if (typeof value.value !== 'object') {
reportFiles.push(
'"' + getMessageFilepath(value.source.fullpath, context) + '"'
`"${getMessageFilepath(value.source.fullpath, context)}"`
)
} else {
nextOtherDictionaries.push({
Expand All @@ -145,7 +147,7 @@ function create(context: RuleContext): RuleListener {
message: `duplicate key '${keyPathStr}' in '${pathStack.locale}'. ${
reportFiles.length === 0
? last
: reportFiles.join(', ') + ', and ' + last
: `${reportFiles.join(', ')}, and ${last}`
} has the same key`,
loc: reportNode.loc
})
Expand Down Expand Up @@ -316,7 +318,7 @@ function create(context: RuleContext): RuleListener {
lm => lm !== targetLocaleMessage
)
return createVisitorForJson(
ctx.getSourceCode(),
getSourceCode(ctx),
targetLocaleMessage,
otherLocaleMessages
)
Expand All @@ -335,31 +337,33 @@ function create(context: RuleContext): RuleListener {
lm => lm !== targetLocaleMessage
)
return createVisitorForYaml(
ctx.getSourceCode(),
getSourceCode(ctx),
targetLocaleMessage,
otherLocaleMessages
)
}
)
} else if (context.parserServices.isJSON || context.parserServices.isYAML) {
} else if (
sourceCode.parserServices.isJSON ||
sourceCode.parserServices.isYAML
) {
const localeMessages = getLocaleMessages(context)
const targetLocaleMessage = localeMessages.findExistLocaleMessage(filename)
if (!targetLocaleMessage) {
debug(`ignore ${filename} in no-duplicate-keys-in-locale`)
return {}
}

const sourceCode = context.getSourceCode()
const otherLocaleMessages: LocaleMessage[] =
localeMessages.localeMessages.filter(lm => lm !== targetLocaleMessage)

if (context.parserServices.isJSON) {
if (sourceCode.parserServices.isJSON) {
return createVisitorForJson(
sourceCode,
targetLocaleMessage,
otherLocaleMessages
)
} else if (context.parserServices.isYAML) {
} else if (sourceCode.parserServices.isYAML) {
return createVisitorForYaml(
sourceCode,
targetLocaleMessage,
Expand Down
5 changes: 3 additions & 2 deletions lib/rules/no-dynamic-keys.ts
Expand Up @@ -5,12 +5,13 @@ import { defineTemplateBodyVisitor, isStaticLiteral } from '../utils/index'
import type { RuleContext, RuleListener } from '../types'
import type { AST as VAST } from 'vue-eslint-parser'
import { createRule } from '../utils/rule'
import { getSourceCode } from '../utils/compat'

function getNodeName(context: RuleContext, node: VAST.Node): string {
if (node.type === 'Identifier') {
return node.name
}
const sourceCode = context.getSourceCode()
const sourceCode = getSourceCode(context)
if (
sourceCode.ast.range[0] <= node.range[0] &&
node.range[1] <= sourceCode.ast.range[1]
Expand All @@ -20,7 +21,7 @@ function getNodeName(context: RuleContext, node: VAST.Node): string {
.map(t => t.value)
.join('')
}
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
const tokenStore = sourceCode.parserServices.getTemplateBodyTokenStore()
return tokenStore
.getTokens(node)
.map(t => t.value)
Expand Down
8 changes: 5 additions & 3 deletions lib/rules/no-html-messages.ts
Expand Up @@ -10,6 +10,7 @@ import type { AST as YAMLAST } from 'yaml-eslint-parser'
import type { RuleContext, RuleListener } from '../types'
import { createRule } from '../utils/rule'
import type { DefaultTreeAdapterMap } from 'parse5'
import { getFilename, getSourceCode } from '../utils/compat'

const debug = debugBuilder('eslint-plugin-vue-i18n:no-html-messages')

Expand All @@ -25,7 +26,8 @@ function findHTMLNode(node: DocumentFragment): Element | undefined {
}

function create(context: RuleContext): RuleListener {
const filename = context.getFilename()
const filename = getFilename(context)
const sourceCode = getSourceCode(context)

/**
* @param {JSONLiteral} node
Expand Down Expand Up @@ -97,14 +99,14 @@ function create(context: RuleContext): RuleListener {
}
}
)
} else if (context.parserServices.isJSON) {
} else if (sourceCode.parserServices.isJSON) {
if (!getLocaleMessages(context).findExistLocaleMessage(filename)) {
return {}
}
return {
JSONLiteral: verifyJSONLiteral
}
} else if (context.parserServices.isYAML) {
} else if (sourceCode.parserServices.isYAML) {
if (!getLocaleMessages(context).findExistLocaleMessage(filename)) {
return {}
}
Expand Down
13 changes: 9 additions & 4 deletions lib/rules/no-missing-keys-in-other-locales.ts
Expand Up @@ -14,12 +14,14 @@ import type {
import type { LocaleMessage, LocaleMessages } from '../utils/locale-messages'
import { joinPath } from '../utils/key-path'
import { createRule } from '../utils/rule'
import { getFilename, getSourceCode } from '../utils/compat'
const debug = debugBuilder(
'eslint-plugin-vue-i18n:no-missing-keys-in-other-locales'
)

function create(context: RuleContext): RuleListener {
const filename = context.getFilename()
const filename = getFilename(context)
const sourceCode = getSourceCode(context)
const ignoreLocales: string[] = context.options[0]?.ignoreLocales || []

function reportMissing(
Expand Down Expand Up @@ -307,17 +309,20 @@ function create(context: RuleContext): RuleListener {
return createVisitorForYaml(targetLocaleMessage, localeMessages)
}
)
} else if (context.parserServices.isJSON || context.parserServices.isYAML) {
} else if (
sourceCode.parserServices.isJSON ||
sourceCode.parserServices.isYAML
) {
const localeMessages = getLocaleMessages(context)
const targetLocaleMessage = localeMessages.findExistLocaleMessage(filename)
if (!targetLocaleMessage) {
debug(`ignore ${filename} in no-missing-keys-in-other-locales`)
return {}
}

if (context.parserServices.isJSON) {
if (sourceCode.parserServices.isJSON) {
return createVisitorForJson(targetLocaleMessage, localeMessages)
} else if (context.parserServices.isYAML) {
} else if (sourceCode.parserServices.isYAML) {
return createVisitorForYaml(targetLocaleMessage, localeMessages)
}
return {}
Expand Down

0 comments on commit a488f15

Please sign in to comment.