1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import { State, Settings } from '../util/state'
import type { TextDocument } from 'vscode-languageserver'
import { RecommendedVariantOrderDiagnostic, DiagnosticKind } from './types'
import { findClassListsInDocument, getClassNamesInClassList } from '../util/find'
import * as jit from '../util/jit'
import { getVariantsFromClassName } from '../util/getVariantsFromClassName'
import { equalExact } from '../util/array'
import semver from 'semver'
export async function getRecommendedVariantOrderDiagnostics(
state: State,
document: TextDocument,
settings: Settings
): Promise<RecommendedVariantOrderDiagnostic[]> {
if (!state.jit) return []
if (semver.gte(state.version, '2.99.0')) return []
let severity = settings.tailwindCSS.lint.recommendedVariantOrder
if (severity === 'ignore') return []
let diagnostics: RecommendedVariantOrderDiagnostic[] = []
const classLists = await findClassListsInDocument(state, document)
classLists.flat().forEach((classList) => {
const classNames = getClassNamesInClassList(classList)
classNames.forEach((className) => {
let { rules } = jit.generateRules(state, [className.className])
if (rules.length === 0) {
return
}
let { variants, offset } = getVariantsFromClassName(state, className.className)
let sortedVariants = [...variants].sort((a, b) =>
jit.bigSign(state.jitContext.variantOrder.get(b) - state.jitContext.variantOrder.get(a))
)
if (!equalExact(variants, sortedVariants)) {
diagnostics.push({
code: DiagnosticKind.RecommendedVariantOrder,
suggestions: [
[...sortedVariants, className.className.substr(offset)].join(state.separator),
],
range: className.range,
severity:
severity === 'error'
? 1 /* DiagnosticSeverity.Error */
: 2 /* DiagnosticSeverity.Warning */,
message:
'Variants are not in the recommended order, which may cause unexpected CSS output.',
})
}
})
})
return diagnostics
}
|