From 81aad28bc83843122937822bd7b33bb3eaeedb08 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Fri, 12 Jun 2020 17:34:59 +0100 Subject: [PATCH] add initial "unsupported tailwind directive" lint rule --- package.json | 15 +++++++ src/lsp/providers/diagnosticsProvider.ts | 50 ++++++++++++++++++++++++ src/lsp/server.ts | 1 + src/lsp/util/state.ts | 1 + 4 files changed, 67 insertions(+) diff --git a/package.json b/package.json index 0aa66cb..055375e 100755 --- a/package.json +++ b/package.json @@ -149,6 +149,21 @@ "", "" ] + }, + "tailwindCSS.lint.unsupportedTailwindDirective": { + "type": "string", + "enum": [ + "ignore", + "warning", + "error" + ], + "default": "error", + "markdownDescription": "", + "markdownEnumDescriptions": [ + "", + "", + "" + ] } } } diff --git a/src/lsp/providers/diagnosticsProvider.ts b/src/lsp/providers/diagnosticsProvider.ts index 18f3bc5..866c07d 100644 --- a/src/lsp/providers/diagnosticsProvider.ts +++ b/src/lsp/providers/diagnosticsProvider.ts @@ -17,6 +17,7 @@ import { getClassNameDecls } from '../util/getClassNameDecls' import { equal, flatten } from '../../util/array' import { getDocumentSettings } from '../util/getDocumentSettings' const dlv = require('dlv') +import semver from 'semver' function getUnsupportedApplyDiagnostics( state: State, @@ -265,6 +266,50 @@ function getUnknownConfigKeyDiagnostics( .filter(Boolean) } +function getUnsupportedTailwindDirectiveDiagnostics( + state: State, + document: TextDocument, + settings: Settings +): Diagnostic[] { + let severity = settings.lint.unsupportedTailwindDirective + if (severity === 'ignore') return [] + + let text = document.getText() + let matches = findAll(/(?:\s|^)@tailwind\s+(?[^;]+)/g, text) + + let allowed = [ + 'utilities', + 'components', + 'screens', + semver.gte(state.version, '1.0.0-beta.1') ? 'base' : 'preflight', + ] + + return matches + .map((match) => { + if (allowed.includes(match.groups.value)) { + return null + } + + return { + range: { + start: indexToPosition( + text, + match.index + match[0].length - match.groups.value.length + ), + end: indexToPosition(text, match.index + match[0].length), + }, + severity: + severity === 'error' + ? DiagnosticSeverity.Error + : DiagnosticSeverity.Warning, + message: `Unsupported value: ${match.groups.value}${ + match.groups.value === 'preflight' ? '. Use base instead.' : '' + }`, + } + }) + .filter(Boolean) +} + export async function provideDiagnostics( state: State, document: TextDocument @@ -280,6 +325,11 @@ export async function provideDiagnostics( ...getUnknownScreenDiagnostics(state, document, settings), ...getUnknownVariantDiagnostics(state, document, settings), ...getUnknownConfigKeyDiagnostics(state, document, settings), + ...getUnsupportedTailwindDirectiveDiagnostics( + state, + document, + settings + ), ] : []), ] diff --git a/src/lsp/server.ts b/src/lsp/server.ts index 3c97071..9c9aa35 100644 --- a/src/lsp/server.ts +++ b/src/lsp/server.ts @@ -43,6 +43,7 @@ const defaultSettings: Settings = { unknownScreen: 'error', unknownVariant: 'error', unknownConfigKey: 'error', + unsupportedTailwindDirective: 'error', }, } let globalSettings: Settings = defaultSettings diff --git a/src/lsp/util/state.ts b/src/lsp/util/state.ts index 45f4106..aa9e0f5 100644 --- a/src/lsp/util/state.ts +++ b/src/lsp/util/state.ts @@ -37,6 +37,7 @@ export type Settings = { unknownScreen: DiagnosticSeveritySetting unknownVariant: DiagnosticSeveritySetting unknownConfigKey: DiagnosticSeveritySetting + unsupportedTailwindDirective: DiagnosticSeveritySetting } }