Skip to content

Commit a31c7ae

Browse files
committed
Add class deprecation diagnostics
1 parent 386394c commit a31c7ae

File tree

10 files changed

+89
-1
lines changed

10 files changed

+89
-1
lines changed

Diff for: packages/tailwindcss-language-server/src/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function getDefaultSettings(): Settings {
2222
rootFontSize: 16,
2323
lint: {
2424
cssConflict: 'warning',
25+
deprecatedClass: 'warning',
2526
invalidApply: 'error',
2627
invalidScreen: 'error',
2728
invalidVariant: 'error',

Diff for: packages/tailwindcss-language-service/src/codeActions/codeActionProvider.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
isInvalidScreenDiagnostic,
1414
isInvalidVariantDiagnostic,
1515
isRecommendedVariantOrderDiagnostic,
16+
isDeprecatedClassDiagnostic,
1617
} from '../diagnostics/types'
1718
import { flatten, dedupeBy } from '../util/array'
1819
import { provideCssConflictCodeActions } from './provideCssConflictCodeActions'
@@ -74,7 +75,8 @@ export async function doCodeActions(
7475
isInvalidTailwindDirectiveDiagnostic(diagnostic) ||
7576
isInvalidScreenDiagnostic(diagnostic) ||
7677
isInvalidVariantDiagnostic(diagnostic) ||
77-
isRecommendedVariantOrderDiagnostic(diagnostic)
78+
isRecommendedVariantOrderDiagnostic(diagnostic) ||
79+
isDeprecatedClassDiagnostic(diagnostic)
7880
) {
7981
return provideSuggestionCodeActions(state, params, diagnostic)
8082
}

Diff for: packages/tailwindcss-language-service/src/codeActions/provideSuggestionCodeActions.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { State } from '../util/state'
22
import type { CodeActionParams, CodeAction } from 'vscode-languageserver'
33
import type {
4+
DeprecatedClassDiagnostic,
45
InvalidConfigPathDiagnostic,
56
InvalidTailwindDirectiveDiagnostic,
67
InvalidScreenDiagnostic,
@@ -12,6 +13,7 @@ export function provideSuggestionCodeActions(
1213
_state: State,
1314
params: CodeActionParams,
1415
diagnostic:
16+
| DeprecatedClassDiagnostic
1517
| InvalidConfigPathDiagnostic
1618
| InvalidTailwindDirectiveDiagnostic
1719
| InvalidScreenDiagnostic

Diff for: packages/tailwindcss-language-service/src/diagnostics/diagnosticsProvider.ts

+5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import { getInvalidVariantDiagnostics } from './getInvalidVariantDiagnostics'
88
import { getInvalidConfigPathDiagnostics } from './getInvalidConfigPathDiagnostics'
99
import { getInvalidTailwindDirectiveDiagnostics } from './getInvalidTailwindDirectiveDiagnostics'
1010
import { getRecommendedVariantOrderDiagnostics } from './getRecommendedVariantOrderDiagnostics'
11+
import { getDeprecatedClassDiagnostics } from './getDeprecatedClassDiagnostics'
1112

1213
export async function doValidate(
1314
state: State,
1415
document: TextDocument,
1516
only: DiagnosticKind[] = [
17+
DiagnosticKind.Deprecation,
1618
DiagnosticKind.CssConflict,
1719
DiagnosticKind.InvalidApply,
1820
DiagnosticKind.InvalidScreen,
@@ -26,6 +28,9 @@ export async function doValidate(
2628

2729
return settings.tailwindCSS.validate
2830
? [
31+
...(only.includes(DiagnosticKind.Deprecation)
32+
? await getDeprecatedClassDiagnostics(state, document, settings)
33+
: []),
2934
...(only.includes(DiagnosticKind.CssConflict)
3035
? await getCssConflictDiagnostics(state, document, settings)
3136
: []),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { joinWithAnd } from '../util/joinWithAnd'
2+
import type { State, Settings } from '../util/state'
3+
import { type DeprecatedClassDiagnostic, DiagnosticKind } from './types'
4+
import { findClassListsInDocument, getClassNamesInClassList } from '../util/find'
5+
import type { TextDocument } from 'vscode-languageserver-textdocument'
6+
7+
export async function getDeprecatedClassDiagnostics(
8+
state: State,
9+
document: TextDocument,
10+
settings: Settings,
11+
): Promise<DeprecatedClassDiagnostic[]> {
12+
// Only v4 projects can report deprecations
13+
if (!state.v4) return []
14+
15+
let severity = settings.tailwindCSS.lint.deprecatedClass
16+
if (severity === 'ignore') return []
17+
18+
let deprecatedClasses = new Set(
19+
state.classList.filter(([_, meta]) => meta.deprecated ?? false).map(([className]) => className),
20+
)
21+
22+
let diagnostics: DeprecatedClassDiagnostic[] = []
23+
let classLists = await findClassListsInDocument(state, document)
24+
25+
for (let classList of classLists) {
26+
let classNames = getClassNamesInClassList(classList, state.blocklist)
27+
28+
for (let className of classNames) {
29+
if (!deprecatedClasses.has(className.className)) continue
30+
31+
diagnostics.push({
32+
code: DiagnosticKind.DeprecatedClass,
33+
className,
34+
range: className.range,
35+
severity:
36+
severity === 'error'
37+
? 1 /* DiagnosticSeverity.Error */
38+
: 2 /* DiagnosticSeverity.Warning */,
39+
message: `'${className.className}' is deprecated.`,
40+
suggestions: [],
41+
})
42+
}
43+
}
44+
45+
return diagnostics
46+
}

Diff for: packages/tailwindcss-language-service/src/diagnostics/types.ts

+14
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,24 @@ export enum DiagnosticKind {
66
InvalidApply = 'invalidApply',
77
InvalidScreen = 'invalidScreen',
88
InvalidVariant = 'invalidVariant',
9+
DeprecatedClass = 'deprecatedClass',
910
InvalidConfigPath = 'invalidConfigPath',
1011
InvalidTailwindDirective = 'invalidTailwindDirective',
1112
RecommendedVariantOrder = 'recommendedVariantOrder',
1213
}
1314

15+
export type DeprecatedClassDiagnostic = Diagnostic & {
16+
code: DiagnosticKind.DeprecatedClass
17+
className: DocumentClassName
18+
suggestions: string[]
19+
}
20+
21+
export function isDeprecatedClassDiagnostic(
22+
diagnostic: AugmentedDiagnostic,
23+
): diagnostic is DeprecatedClassDiagnostic {
24+
return diagnostic.code === DiagnosticKind.DeprecatedClass
25+
}
26+
1427
export type CssConflictDiagnostic = Diagnostic & {
1528
code: DiagnosticKind.CssConflict
1629
className: DocumentClassName
@@ -90,6 +103,7 @@ export function isRecommendedVariantOrderDiagnostic(
90103
}
91104

92105
export type AugmentedDiagnostic =
106+
| DeprecatedClassDiagnostic
93107
| CssConflictDiagnostic
94108
| InvalidApplyDiagnostic
95109
| InvalidScreenDiagnostic

Diff for: packages/tailwindcss-language-service/src/util/state.ts

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export type TailwindCssSettings = {
5454
colorDecorators: boolean
5555
lint: {
5656
cssConflict: DiagnosticSeveritySetting
57+
deprecatedClass: DiagnosticSeveritySetting
5758
invalidApply: DiagnosticSeveritySetting
5859
invalidScreen: DiagnosticSeveritySetting
5960
invalidVariant: DiagnosticSeveritySetting
@@ -91,6 +92,7 @@ export interface Variant {
9192
export interface ClassMetadata {
9293
color: culori.Color | KeywordColor | null
9394
modifiers?: string[]
95+
deprecated?: boolean
9496
}
9597

9698
export interface State {

Diff for: packages/vscode-tailwindcss/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Fix display of color swatches using new v4 oklch color palette ([#1073](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1073))
66
- Properly validate `theme(…)` function paths in v4 ([#1074](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1074))
77
- Show all potential class conflicts in v4 projects ([#1077](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1077))
8+
- Add support for detecting deprecated classes ([#1084](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1084))
89

910
## 0.12.11
1011

Diff for: packages/vscode-tailwindcss/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ Unknown or invalid path used with the [`theme` helper](https://tailwindcss.com/d
148148

149149
Class names on the same HTML element which apply the same CSS property or properties. **Default: `warning`**
150150

151+
#### `tailwindCSS.lint.deprecatedClass`
152+
153+
Use of a deprecated class. **Default: `warning`**
154+
151155
#### `tailwindCSS.lint.recommendedVariantOrder`
152156

153157
Class variants not in the recommended order (applies in [JIT mode](https://tailwindcss.com/docs/just-in-time-mode) only). **Default: `warning`**

Diff for: packages/vscode-tailwindcss/package.json

+11
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,17 @@
225225
"markdownDescription": "Class names on the same HTML element which apply the same CSS property or properties",
226226
"scope": "language-overridable"
227227
},
228+
"tailwindCSS.lint.deprecatedClass": {
229+
"type": "string",
230+
"enum": [
231+
"ignore",
232+
"warning",
233+
"error"
234+
],
235+
"default": "warning",
236+
"markdownDescription": "Use of a deprecated utility class",
237+
"scope": "language-overridable"
238+
},
228239
"tailwindCSS.lint.invalidApply": {
229240
"type": "string",
230241
"enum": [

0 commit comments

Comments
 (0)