diff --git a/src/lsp/providers/diagnostics/getInvalidApplyDiagnostics.ts b/src/lsp/providers/diagnostics/getInvalidApplyDiagnostics.ts index e829b5735e74900f08d5d7161c5d561eebd7b89f..66fc540125ce57a44e5550b89d9b6f1551085141 100644 --- a/src/lsp/providers/diagnostics/getInvalidApplyDiagnostics.ts +++ b/src/lsp/providers/diagnostics/getInvalidApplyDiagnostics.ts @@ -2,7 +2,7 @@ import { findClassNamesInRange } from '../../util/find' import { InvalidApplyDiagnostic, DiagnosticKind } from './types' import { Settings, State } from '../../util/state' import { TextDocument, DiagnosticSeverity } from 'vscode-languageserver' -import { validateApply } from '../../util/validateApply' +import { getClassNameMeta } from '../../util/getClassNameMeta' export function getInvalidApplyDiagnostics( state: State, @@ -15,12 +15,39 @@ const classNames = findClassNamesInRange(document, undefined, 'css') let diagnostics: InvalidApplyDiagnostic[] = classNames.map((className) => { - let result = validateApply(state, className.className) + const meta = getClassNameMeta(state, className.className) + if (!meta) return null - if (result === null || result.isApplyable === true) { - return null + let message: string + + if (Array.isArray(meta)) { + message = `'@apply' cannot be used with '${className.className}' because it is included in multiple rulesets.` + } else if (meta.source !== 'utilities') { + message = `'@apply' cannot be used with '${className.className}' because it is not a utility.` + } else if (meta.context && meta.context.length > 0) { + if (meta.context.length === 1) { + message = `'@apply' cannot be used with '${className.className}' because it is nested inside of an at-rule ('${meta.context[0]}').` + } else { + message = `'@apply' cannot be used with '${ + className.className + }' because it is nested inside of at-rules (${meta.context + .map((c) => `'${c}'`) + .join(', ')}).` + } + } else if (meta.pseudo && meta.pseudo.length > 0) { + if (meta.pseudo.length === 1) { + message = `'@apply' cannot be used with '${className.className}' because its definition includes a pseudo-selector ('${meta.pseudo[0]}')` + } else { + message = `'@apply' cannot be used with '${ + className.className + }' because its definition includes pseudo-selectors (${meta.pseudo + .map((p) => `'${p}'`) + .join(', ')}).` + } } + if (!message) return null + return { code: DiagnosticKind.InvalidApply, severity: @@ -28,7 +55,7 @@ severity === 'error' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning, range: className.range, - message: result.reason, + message, className, } }) diff --git a/src/lsp/providers/hoverProvider.ts b/src/lsp/providers/hoverProvider.ts index 2084ec42933cbf2cfc02ead3b476698727a2d89e..a9010a3142cb4e9700f63e3bd06426a144b9afa0 100644 --- a/src/lsp/providers/hoverProvider.ts +++ b/src/lsp/providers/hoverProvider.ts @@ -1,11 +1,10 @@ import { State } from '../util/state' import { Hover, TextDocumentPositionParams } from 'vscode-languageserver' +import { getClassNameParts } from '../util/getClassNameAtPosition' import { stringifyCss, stringifyConfigValue } from '../util/stringify' const dlv = require('dlv') import { isCssContext } from '../util/css' import { findClassNameAtPosition } from '../util/find' -import { validateApply } from '../util/validateApply' -import { getClassNameParts } from '../util/getClassNameAtPosition' export function provideHover( state: State, @@ -81,13 +80,6 @@ if (className === null) return null const parts = getClassNameParts(state, className.className) if (!parts) return null - - if (isCssContext(state, doc, position)) { - let validated = validateApply(state, parts) - if (validated === null || validated.isApplyable === false) { - return null - } - } return { contents: { diff --git a/src/lsp/util/validateApply.ts b/src/lsp/util/validateApply.ts deleted file mode 100644 index 52f2b2c432fc5d85f448a1e9560683dc75a5bfed..0000000000000000000000000000000000000000 --- a/src/lsp/util/validateApply.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { State } from './state' -import { getClassNameMeta } from './getClassNameMeta' - -export function validateApply( - state: State, - classNameOrParts: string | string[] -): { isApplyable: true } | { isApplyable: false; reason: string } | null { - const meta = getClassNameMeta(state, classNameOrParts) - if (!meta) return null - - const className = Array.isArray(classNameOrParts) - ? classNameOrParts.join(state.separator) - : classNameOrParts - - let reason: string - - if (Array.isArray(meta)) { - reason = `'@apply' cannot be used with '${className}' because it is included in multiple rulesets.` - } else if (meta.source !== 'utilities') { - reason = `'@apply' cannot be used with '${className}' because it is not a utility.` - } else if (meta.context && meta.context.length > 0) { - if (meta.context.length === 1) { - reason = `'@apply' cannot be used with '${className}' because it is nested inside of an at-rule ('${meta.context[0]}').` - } else { - reason = `'@apply' cannot be used with '${className}' because it is nested inside of at-rules (${meta.context - .map((c) => `'${c}'`) - .join(', ')}).` - } - } else if (meta.pseudo && meta.pseudo.length > 0) { - if (meta.pseudo.length === 1) { - reason = `'@apply' cannot be used with '${className}' because its definition includes a pseudo-selector ('${meta.pseudo[0]}')` - } else { - reason = `'@apply' cannot be used with '${className}' because its definition includes pseudo-selectors (${meta.pseudo - .map((p) => `'${p}'`) - .join(', ')}).` - } - } - - if (reason) { - return { isApplyable: false, reason } - } - - return { isApplyable: true } -}