Skip to content

Commit

Permalink
fix: support v10
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi committed Dec 9, 2024
1 parent 437652d commit 677b046
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 102 deletions.
4 changes: 1 addition & 3 deletions lib/rules/no-deprecated-modulo-syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
getMessageSyntaxVersions,
NodeTypes
} from '../utils/message-compiler/utils'
import { parse } from '../utils/message-compiler/parser'
import { parse } from '../utils/message-compiler/parser-v9'
import { traverseNode } from '../utils/message-compiler/traverser'
import {
createRule,
Expand Down Expand Up @@ -75,8 +75,6 @@ function create(context: RuleContext): RuleListener {
}
if (messageSyntaxVersions.v9) {
verifyForV9(message, reportNode, getReportOffset)
} else if (messageSyntaxVersions.v8) {
return
}
}

Expand Down
12 changes: 7 additions & 5 deletions lib/rules/prefer-linked-key-with-paren.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function create(context: RuleContext): RuleListener {
const sourceCode = getSourceCode(context)
const messageSyntaxVersions = getMessageSyntaxVersions(context)

function verifyForV9(
function verifyForNewSyntax(
message: string,
reportNode: JSONAST.JSONStringLiteral | YAMLAST.YAMLScalar,
getReportOffset: GetReportOffset
Expand Down Expand Up @@ -134,14 +134,16 @@ function create(context: RuleContext): RuleListener {
if (messageSyntaxVersions.reportIfMissingSetting()) {
return
}
if (messageSyntaxVersions.v9 && messageSyntaxVersions.v8) {
const newSyntax = messageSyntaxVersions.v9 || messageSyntaxVersions.v10
const v8Syntax = messageSyntaxVersions.v8
if (newSyntax && v8Syntax) {
// This rule cannot support two versions in the same project.
return
}

if (messageSyntaxVersions.v9) {
verifyForV9(message, reportNode, getReportOffset)
} else if (messageSyntaxVersions.v8) {
if (newSyntax) {
verifyForNewSyntax(message, reportNode, getReportOffset)
} else if (v8Syntax) {
verifyForV8(message, reportNode, getReportOffset)
}
}
Expand Down
12 changes: 10 additions & 2 deletions lib/rules/valid-message-syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
getReportIndex
} from '../utils/message-compiler/utils'
import { parse } from '../utils/message-compiler/parser'
import { parse as parseForV9 } from '../utils/message-compiler/parser-v9'
import { parse as parseForV8 } from '../utils/message-compiler/parser-v8'
import type { CompileError } from '@intlify/message-compiler'
import { createRule } from '../utils/rule'
Expand All @@ -27,9 +28,16 @@ function create(context: RuleContext): RuleListener {
const messageSyntaxVersions = getMessageSyntaxVersions(context)

function* extractMessageErrors(message: string) {
if (messageSyntaxVersions.v9) {
yield* parse(message).errors
// v10 and v9 generate nearly identical errors so only one of them will be returned.
const errorsForV10OrV9: CompileError[] = []
if (messageSyntaxVersions.v10) {
errorsForV10OrV9.push(...parse(message).errors)
}
if (messageSyntaxVersions.v9 && !errorsForV10OrV9.length) {
errorsForV10OrV9.push(...parseForV9(message).errors)
}
yield* errorsForV10OrV9

if (messageSyntaxVersions.v8) {
yield* parseForV8(message).errors
}
Expand Down
6 changes: 5 additions & 1 deletion lib/utils/collect-linked-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { ResourceNode } from '@intlify/message-compiler'
import { traverseNode } from './message-compiler/traverser'
import type { I18nLocaleMessageDictionary, RuleContext } from '../types'
import { parse } from './message-compiler/parser'
import { parse as parseForV9 } from './message-compiler/parser-v9'
import { parse as parseForV8 } from './message-compiler/parser-v8'
import type { MessageSyntaxVersions } from './message-compiler/utils'
import { NodeTypes } from './message-compiler/utils'
Expand All @@ -27,9 +28,12 @@ function* extractUsedKeysFromLinks(
if (typeof value === 'object') {
yield* extractUsedKeysFromLinks(value, messageSyntaxVersions)
} else if (typeof value === 'string') {
if (messageSyntaxVersions.v9) {
if (messageSyntaxVersions.v10) {
yield* extractUsedKeysFromAST(parse(value).ast)
}
if (messageSyntaxVersions.v9) {
yield* extractUsedKeysFromAST(parseForV9(value).ast)
}
if (messageSyntaxVersions.v8) {
yield* extractUsedKeysFromAST(parseForV8(value).ast)
}
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/message-compiler/parser-v8.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
} from '@intlify/message-compiler'
import { sortedLastIndex } from 'lodash'
import { NodeTypes } from './utils'
import type { ModuloNamedNode } from './parser-v9'

export function parse(code: string): {
ast: ResourceNode
Expand Down Expand Up @@ -207,7 +208,7 @@ function parseAST(code: string, errors: CompileError[]): ResourceNode {
node = listNode
}
if (!node) {
const namedNode: NamedNode = {
const namedNode: ModuloNamedNode = {
type: NodeTypes.Named,
key: trimmedKeyValue,
...ctx.getNodeLoc(endOffset - 1, placeholderEndOffset)
Expand Down
59 changes: 59 additions & 0 deletions lib/utils/message-compiler/parser-v9.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* A simplified version of the message parser that handles messages like vue-i18n v8.
* This parser probably has poor performance.
*/
import type {
CompileError,
NamedNode,
ResourceNode
} from '@intlify/message-compiler'
import { NodeTypes } from './utils'
import { parse as baseParse } from './parser'
import type { MessageElementNode } from './traverser'
import { traverseNode } from './traverser'

// The deprecated Rails i18n format.
export type ModuloNamedNode = NamedNode & { modulo?: boolean }

export function parse(code: string): {
ast: ResourceNode
errors: CompileError[]
} {
const { ast, errors } = baseParse(code)

traverseNode(ast, node => {
if (node.type === NodeTypes.Message) {
transformModuloNamedNode(node.items)
}
})
return {
ast,
errors
}

function transformModuloNamedNode(nodes: MessageElementNode[]) {
// Converts nodes with a '%' before the brackets into modulo nodes.
for (let index = nodes.length - 1; index >= 1; index--) {
const node = nodes[index]
if (
node.type !== NodeTypes.Named ||
code[node.loc!.start.offset - 1] !== '%'
)
continue

const prev = nodes[index - 1]
if (prev.type !== NodeTypes.Text || !prev.value?.endsWith('%')) continue

node.modulo = true

prev.loc!.end.offset -= 1
prev.loc!.end.column -= 1
prev.end! -= 1
prev.value = prev.value!.slice(0, -1)
if (prev.start === prev.end) {
nodes.splice(index - 1, 1)
index--
}
}
}
}
4 changes: 3 additions & 1 deletion lib/utils/message-compiler/traverser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import type {
TextNode
} from '@intlify/message-compiler'
import { NodeTypes } from './utils'
import type { ModuloNamedNode } from './parser-v9'

type MessageElementNode =
export type MessageElementNode =
| TextNode
| NamedNode
| ListNode
| LiteralNode
| LinkedNode
| ModuloNamedNode
type MessageASTNode =
| ResourceNode
| PluralNode
Expand Down
5 changes: 4 additions & 1 deletion lib/utils/message-compiler/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const NodeTypes = {
export type MessageSyntaxVersions = {
v8: boolean
v9: boolean
v10: boolean
isNotSet: boolean
reportIfMissingSetting: () => boolean
}
Expand All @@ -37,6 +38,7 @@ export function getMessageSyntaxVersions(
return {
v8: true,
v9: true,
v10: true,
isNotSet: true,
reportIfMissingSetting: () => {
if (!puttedSettingsError.has(context)) {
Expand All @@ -54,7 +56,8 @@ export function getMessageSyntaxVersions(
const range = new Range(messageSyntaxVersion)
return {
v8: intersects(range, '^8.0.0 || <=8.0.0'),
v9: intersects(range, '>=9.0.0-0'),
v9: intersects(range, '^9.0.0-0'),
v10: intersects(range, '>=10.0.0-0'),
isNotSet: false,
reportIfMissingSetting: () => false
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"dependencies": {
"@eslint/eslintrc": "^3.0.0",
"@intlify/core-base": "^10.0.0",
"@intlify/message-compiler": "^10.0.0",
"@intlify/message-compiler": "^10.0.5",
"debug": "^4.3.4",
"eslint-compat-utils": "^0.6.0",
"glob": "^10.3.3",
Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/lib/rules/no-deprecated-modulo-syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const tester = new RuleTester({
languageOptions: { parser: vueParser, ecmaVersion: 2015 }
})

tester.run('no-deprecated-module-syntax', rule as never, {
tester.run('no-deprecated-modulo-syntax', rule as never, {
valid: [
// text only
{
Expand Down
Loading

0 comments on commit 677b046

Please sign in to comment.