diff --git a/packages/tailwindcss-language-server/src/testing/index.ts b/packages/tailwindcss-language-server/src/testing/index.ts index 0a11bb9d..efce9fd2 100644 --- a/packages/tailwindcss-language-server/src/testing/index.ts +++ b/packages/tailwindcss-language-server/src/testing/index.ts @@ -3,7 +3,7 @@ import * as os from 'node:os' import * as fs from 'node:fs/promises' import * as path from 'node:path' import * as proc from 'node:child_process' -import dedent from 'dedent' +import dedent, { type Dedent } from 'dedent' export interface TestUtils> { /** The "cwd" for this test */ @@ -160,8 +160,8 @@ async function installDependenciesIn(dir: string) { }) } -export const css = dedent -export const scss = dedent -export const html = dedent -export const js = dedent -export const json = dedent +export const css: Dedent = dedent +export const scss: Dedent = dedent +export const html: Dedent = dedent +export const js: Dedent = dedent +export const json: Dedent = dedent diff --git a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts index dcbda0e0..0ead7b36 100644 --- a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts +++ b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts @@ -212,7 +212,7 @@ function classNameToAst( obj = rule } - return cssObjToAst(obj, state.modules.postcss) + return cssObjToAst(obj, state.modules.postcss.module) } function appendPseudosToSelector(selector: string, pseudos: string[]): string | null { diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 843e9a8e..bf9685a9 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -2230,7 +2230,7 @@ export async function doComplete( document: TextDocument, position: Position, context?: CompletionContext, -) { +): Promise { if (state === null) return { items: [], isIncomplete: false } const result = diff --git a/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts index ec6dc166..dcf61089 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts @@ -239,7 +239,7 @@ export function visit( nodes: postcss.AnyNode[], cb: (node: postcss.AnyNode, path: postcss.AnyNode[]) => void, path: postcss.AnyNode[] = [], -) { +): void { for (let child of nodes) { path = [...path, child] cb(child, path) diff --git a/packages/tailwindcss-language-service/src/metadata/extensions.ts b/packages/tailwindcss-language-service/src/metadata/extensions.ts index 15babe94..34726d8f 100644 --- a/packages/tailwindcss-language-service/src/metadata/extensions.ts +++ b/packages/tailwindcss-language-service/src/metadata/extensions.ts @@ -72,5 +72,5 @@ let templateExtensions = [ 'rs', ] -export const IS_SCRIPT_SOURCE = new RegExp(`\\.(${scriptExtensions.join('|')})$`) -export const IS_TEMPLATE_SOURCE = new RegExp(`\\.(${templateExtensions.join('|')})$`) +export const IS_SCRIPT_SOURCE: RegExp = new RegExp(`\\.(${scriptExtensions.join('|')})$`) +export const IS_TEMPLATE_SOURCE: RegExp = new RegExp(`\\.(${templateExtensions.join('|')})$`) diff --git a/packages/tailwindcss-language-service/src/util/absoluteRange.ts b/packages/tailwindcss-language-service/src/util/absoluteRange.ts index 643de4ed..de6cb642 100644 --- a/packages/tailwindcss-language-service/src/util/absoluteRange.ts +++ b/packages/tailwindcss-language-service/src/util/absoluteRange.ts @@ -1,6 +1,6 @@ import type { Range } from 'vscode-languageserver' -export function absoluteRange(range: Range, reference?: Range) { +export function absoluteRange(range: Range, reference?: Range): Range { return { start: { line: (reference?.start.line || 0) + range.start.line, diff --git a/packages/tailwindcss-language-service/src/util/braceLevel.ts b/packages/tailwindcss-language-service/src/util/braceLevel.ts index a7245b17..46d2f5cd 100644 --- a/packages/tailwindcss-language-service/src/util/braceLevel.ts +++ b/packages/tailwindcss-language-service/src/util/braceLevel.ts @@ -1,4 +1,4 @@ -export function braceLevel(text: string) { +export function braceLevel(text: string): number { let count = 0 for (let i = text.length - 1; i >= 0; i--) { @@ -10,7 +10,7 @@ export function braceLevel(text: string) { return count } -export function parenLevel(text: string) { +export function parenLevel(text: string): number { let count = 0 for (let i = text.length - 1; i >= 0; i--) { diff --git a/packages/tailwindcss-language-service/src/util/colorEquivalents.ts b/packages/tailwindcss-language-service/src/util/colorEquivalents.ts index 95ab47bc..a33f9070 100644 --- a/packages/tailwindcss-language-service/src/util/colorEquivalents.ts +++ b/packages/tailwindcss-language-service/src/util/colorEquivalents.ts @@ -1,4 +1,4 @@ -import type { Plugin } from 'postcss' +import type { Plugin, PluginCreator } from 'postcss' import parseValue from 'postcss-value-parser' import { inGamut } from 'culori' import { formatColor, getColorFromValue } from './color' @@ -16,51 +16,55 @@ export function getEquivalentColor(value: string): string { return formatColor(color) } -export function equivalentColorValues({ comments }: { comments: Comment[] }): Plugin { - return { - postcssPlugin: 'plugin', - Declaration(decl) { - if (!allowedFunctions.some((fn) => decl.value.includes(fn))) { - return - } - - parseValue(decl.value).walk((node) => { - if (node.type !== 'function') { - return true +export const equivalentColorValues: PluginCreator = Object.assign( + ({ comments }: { comments: Comment[] }): Plugin => { + return { + postcssPlugin: 'plugin', + Declaration(decl) { + if (!allowedFunctions.some((fn) => decl.value.includes(fn))) { + return } - if (node.value === 'var') { - return true - } + parseValue(decl.value).walk((node) => { + if (node.type !== 'function') { + return true + } - if (!allowedFunctions.includes(node.value)) { - return false - } + if (node.value === 'var') { + return true + } - const values = node.nodes.filter((n) => n.type === 'word').map((n) => n.value) - if (values.length < 3) { - return false - } + if (!allowedFunctions.includes(node.value)) { + return false + } - let color = `${node.value}(${values.join(' ')})` + const values = node.nodes.filter((n) => n.type === 'word').map((n) => n.value) + if (values.length < 3) { + return false + } - let equivalent = getEquivalentColor(color) + let color = `${node.value}(${values.join(' ')})` - if (equivalent === color) { - return false - } + let equivalent = getEquivalentColor(color) - comments.push({ - index: - decl.source.start.offset + - `${decl.prop}${decl.raws.between}`.length + - node.sourceEndIndex, - value: equivalent, - }) + if (equivalent === color) { + return false + } - return false - }) - }, - } -} -equivalentColorValues.postcss = true + comments.push({ + index: + decl.source.start.offset + + `${decl.prop}${decl.raws.between}`.length + + node.sourceEndIndex, + value: equivalent, + }) + + return false + }) + }, + } + }, + { + postcss: true as const, + }, +) diff --git a/packages/tailwindcss-language-service/src/util/css.ts b/packages/tailwindcss-language-service/src/util/css.ts index c5f3e3a4..f43219aa 100644 --- a/packages/tailwindcss-language-service/src/util/css.ts +++ b/packages/tailwindcss-language-service/src/util/css.ts @@ -6,7 +6,7 @@ import type { State } from './state' import { cssLanguages } from './languages' import { getLanguageBoundaries } from './getLanguageBoundaries' -function getCssLanguages(state: State) { +function getCssLanguages(state: State): string[] { const userCssLanguages = Object.keys(state.editor.userLanguages).filter((lang) => cssLanguages.includes(state.editor.userLanguages[lang]), ) @@ -14,7 +14,7 @@ function getCssLanguages(state: State) { return [...cssLanguages, ...userCssLanguages] } -export function isCssLanguage(state: State, lang: string) { +export function isCssLanguage(state: State, lang: string): boolean { return getCssLanguages(state).indexOf(lang) !== -1 } diff --git a/packages/tailwindcss-language-service/src/util/cssObjToAst.ts b/packages/tailwindcss-language-service/src/util/cssObjToAst.ts index 42826f75..ce151bdd 100644 --- a/packages/tailwindcss-language-service/src/util/cssObjToAst.ts +++ b/packages/tailwindcss-language-service/src/util/cssObjToAst.ts @@ -120,7 +120,9 @@ function parse(obj, parent, postcss) { } } -export function cssObjToAst(obj, postcss) { +import type { Postcss, Root } from 'postcss' + +export function cssObjToAst(obj: any, postcss: Postcss): Root { var root = postcss.root() parse(obj, root, postcss) return root diff --git a/packages/tailwindcss-language-service/src/util/estimated-class-size.ts b/packages/tailwindcss-language-service/src/util/estimated-class-size.ts index 57dc4235..2e6eb36a 100644 --- a/packages/tailwindcss-language-service/src/util/estimated-class-size.ts +++ b/packages/tailwindcss-language-service/src/util/estimated-class-size.ts @@ -6,7 +6,7 @@ import { segment } from './segment' * This is meant to be a lower bound, as the actual size of a class can vary * depending on the actual CSS properties and values, configured theme, etc… */ -export function estimatedClassSize(className: string) { +export function estimatedClassSize(className: string): number { let size = 0 // We estimate the size using the following structure which gives a reasonable diff --git a/packages/tailwindcss-language-service/src/util/flagEnabled.ts b/packages/tailwindcss-language-service/src/util/flagEnabled.ts index f6f4dd02..70b7776a 100644 --- a/packages/tailwindcss-language-service/src/util/flagEnabled.ts +++ b/packages/tailwindcss-language-service/src/util/flagEnabled.ts @@ -1,7 +1,7 @@ import type { State } from './state' import dlv from 'dlv' -export function flagEnabled(state: State, flag: string) { +export function flagEnabled(state: State, flag: string): boolean { if (state.featureFlags.future.includes(flag)) { return state.config.future === 'all' || dlv(state.config, ['future', flag], false) } diff --git a/packages/tailwindcss-language-service/src/util/format-bytes.ts b/packages/tailwindcss-language-service/src/util/format-bytes.ts index a7b0b050..36b27159 100644 --- a/packages/tailwindcss-language-service/src/util/format-bytes.ts +++ b/packages/tailwindcss-language-service/src/util/format-bytes.ts @@ -1,6 +1,6 @@ const UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte'] -export function formatBytes(n: number) { +export function formatBytes(n: number): string { let i = n == 0 ? 0 : Math.floor(Math.log(n) / Math.log(1000)) return new Intl.NumberFormat('en', { notation: 'compact', diff --git a/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts b/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts index 42a4a495..786cc2f7 100644 --- a/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts +++ b/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts @@ -139,7 +139,7 @@ let vueLexer = moo.states(vueStates) let cache = new Cache({ max: 25, maxAge: 1000 }) -export function clearLanguageBoundariesCache() { +export function clearLanguageBoundariesCache(): void { cache.clear() } diff --git a/packages/tailwindcss-language-service/src/util/jit.ts b/packages/tailwindcss-language-service/src/util/jit.ts index ca95df7f..b2a1b218 100644 --- a/packages/tailwindcss-language-service/src/util/jit.ts +++ b/packages/tailwindcss-language-service/src/util/jit.ts @@ -4,7 +4,7 @@ import { addPixelEquivalentsToValue } from './pixelEquivalents' import { addEquivalents } from './equivalents' import { addThemeValues, inlineThemeValues } from './rewriting' -export function bigSign(bigIntValue) { +export function bigSign(bigIntValue: number | bigint): number { // @ts-ignore return (bigIntValue > 0n) - (bigIntValue < 0n) } diff --git a/packages/tailwindcss-language-service/src/util/language-blocks.ts b/packages/tailwindcss-language-service/src/util/language-blocks.ts index 10a3fe14..5fbc038c 100644 --- a/packages/tailwindcss-language-service/src/util/language-blocks.ts +++ b/packages/tailwindcss-language-service/src/util/language-blocks.ts @@ -1,5 +1,5 @@ import type { State } from '../util/state' -import { type Range } from 'vscode-languageserver' +import type { Range } from 'vscode-languageserver' import type { TextDocument } from 'vscode-languageserver-textdocument' import { getLanguageBoundaries } from '../util/getLanguageBoundaries' import { isCssDoc } from '../util/css' diff --git a/packages/tailwindcss-language-service/src/util/languages.ts b/packages/tailwindcss-language-service/src/util/languages.ts index 7a00d1f7..2e5fce74 100644 --- a/packages/tailwindcss-language-service/src/util/languages.ts +++ b/packages/tailwindcss-language-service/src/util/languages.ts @@ -1,6 +1,6 @@ import type { EditorState } from './state' -export const htmlLanguages = [ +export const htmlLanguages: string[] = [ 'aspnetcorerazor', 'astro', 'astro-markdown', @@ -36,7 +36,7 @@ export const htmlLanguages = [ 'twig', ] -export const cssLanguages = [ +export const cssLanguages: string[] = [ 'css', 'less', 'postcss', @@ -47,7 +47,7 @@ export const cssLanguages = [ 'tailwindcss', ] -export const jsLanguages = [ +export const jsLanguages: string[] = [ 'javascript', 'javascriptreact', 'reason', @@ -58,16 +58,21 @@ export const jsLanguages = [ 'glimmer-ts', ] -export const specialLanguages = ['vue', 'svelte'] +export const specialLanguages: string[] = ['vue', 'svelte'] -export const languages = [...cssLanguages, ...htmlLanguages, ...jsLanguages, ...specialLanguages] +export const languages: string[] = [ + ...cssLanguages, + ...htmlLanguages, + ...jsLanguages, + ...specialLanguages, +] const semicolonlessLanguages = ['sass', 'sugarss', 'stylus'] export function isSemicolonlessCssLanguage( languageId: string, userLanguages: EditorState['userLanguages'] = {}, -) { +): boolean { return ( semicolonlessLanguages.includes(languageId) || semicolonlessLanguages.includes(userLanguages[languageId]) diff --git a/packages/tailwindcss-language-service/src/util/lexers.ts b/packages/tailwindcss-language-service/src/util/lexers.ts index a8315f51..cfd062b5 100644 --- a/packages/tailwindcss-language-service/src/util/lexers.ts +++ b/packages/tailwindcss-language-service/src/util/lexers.ts @@ -1,5 +1,5 @@ import moo from 'moo' -import { lazy } from './lazy' +import { Lazy, lazy } from './lazy' const classAttributeStates: () => { [x: string]: moo.Rules } = () => ({ doubleClassList: { @@ -66,7 +66,7 @@ const simpleClassAttributeStates: { [x: string]: moo.Rules } = { }, } -export const getClassAttributeLexer = lazy(() => { +export const getClassAttributeLexer: Lazy = lazy(() => { let supportsNegativeLookbehind = true try { new RegExp('(? { return moo.states(simpleClassAttributeStates) }) -export const getComputedClassAttributeLexer = lazy(() => { +export const getComputedClassAttributeLexer: Lazy = lazy(() => { let supportsNegativeLookbehind = true try { new RegExp('(? = Object.assign( + ({ comments, rootFontSize }: { comments: Comment[]; rootFontSize: number }): Plugin => { + return { + postcssPlugin: 'plugin', + AtRule: { + media(atRule) { + if (!atRule.params.includes('em')) { + return + } + + comments.push( + ...getPixelEquivalentsForMediaQuery(atRule.params).map(({ index, value }) => ({ + index: index + atRule.source.start.offset + `@media${atRule.raws.afterName}`.length, + value, + })), + ) + }, + }, + Declaration(decl) { + if (!decl.value.includes('rem')) { return } - comments.push( - ...getPixelEquivalentsForMediaQuery(atRule.params).map(({ index, value }) => ({ - index: index + atRule.source.start.offset + `@media${atRule.raws.afterName}`.length, - value, - })), - ) - }, - }, - Declaration(decl) { - if (!decl.value.includes('rem')) { - return - } - - parseValue(decl.value).walk((node) => { - if (node.type !== 'word') { - return true - } + parseValue(decl.value).walk((node) => { + if (node.type !== 'word') { + return true + } - let unit = parseValue.unit(node.value) - if (!unit || unit.unit !== 'rem') { - return false - } + let unit = parseValue.unit(node.value) + if (!unit || unit.unit !== 'rem') { + return false + } - comments.push({ - index: - decl.source.start.offset + - `${decl.prop}${decl.raws.between}`.length + - node.sourceEndIndex, - value: `${parseFloat(unit.number) * rootFontSize}px`, - }) + comments.push({ + index: + decl.source.start.offset + + `${decl.prop}${decl.raws.between}`.length + + node.sourceEndIndex, + value: `${parseFloat(unit.number) * rootFontSize}px`, + }) - return false - }) - }, - } -} -equivalentPixelValues.postcss = true + return false + }) + }, + } + }, + { + postcss: true as const, + }, +) diff --git a/packages/tailwindcss-language-service/src/util/rewriting/add-theme-values.ts b/packages/tailwindcss-language-service/src/util/rewriting/add-theme-values.ts index b0f30891..c84d6751 100644 --- a/packages/tailwindcss-language-service/src/util/rewriting/add-theme-values.ts +++ b/packages/tailwindcss-language-service/src/util/rewriting/add-theme-values.ts @@ -7,7 +7,7 @@ import { applyComments, Comment } from '../comments' import { getEquivalentColor } from '../colorEquivalents' import { resolveVariableValue } from './lookup' -export function addThemeValues(css: string, state: State, settings: TailwindCssSettings) { +export function addThemeValues(css: string, state: State, settings: TailwindCssSettings): string { if (!state.designSystem) return css let comments: Comment[] = [] diff --git a/packages/tailwindcss-language-service/src/util/rewriting/inline-theme-values.ts b/packages/tailwindcss-language-service/src/util/rewriting/inline-theme-values.ts index c002ab9c..5c1eb8ed 100644 --- a/packages/tailwindcss-language-service/src/util/rewriting/inline-theme-values.ts +++ b/packages/tailwindcss-language-service/src/util/rewriting/inline-theme-values.ts @@ -4,7 +4,7 @@ import { evaluateExpression } from './calc' import { resolveVariableValue } from './lookup' import { replaceCssVars, replaceCssCalc } from './replacements' -export function inlineThemeValues(css: string, state: State) { +export function inlineThemeValues(css: string, state: State): string { if (!state.designSystem) return css css = replaceCssCalc(css, (expr) => { diff --git a/packages/tailwindcss-language-service/src/util/rewriting/lookup.ts b/packages/tailwindcss-language-service/src/util/rewriting/lookup.ts index 2dbb7146..5f7f353e 100644 --- a/packages/tailwindcss-language-service/src/util/rewriting/lookup.ts +++ b/packages/tailwindcss-language-service/src/util/rewriting/lookup.ts @@ -1,7 +1,7 @@ import { DesignSystem } from '../v4' // Resolve a variable value from the design system -export function resolveVariableValue(design: DesignSystem, name: string) { +export function resolveVariableValue(design: DesignSystem, name: string): string | null { let prefix = design.theme.prefix ?? null if (prefix && name.startsWith(`--${prefix}`)) { diff --git a/packages/tailwindcss-language-service/src/util/segment.ts b/packages/tailwindcss-language-service/src/util/segment.ts index 018485db..70faec52 100644 --- a/packages/tailwindcss-language-service/src/util/segment.ts +++ b/packages/tailwindcss-language-service/src/util/segment.ts @@ -26,7 +26,7 @@ const closingBracketStack = new Uint8Array(256) * x x x ╰──────── Split because top-level * ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens */ -export function segment(input: string, separator: string) { +export function segment(input: string, separator: string): string[] { // SAFETY: We can use an index into a shared buffer because this function is // synchronous, non-recursive, and runs in a single-threaded environment. let stackPos = 0 diff --git a/packages/tailwindcss-language-service/src/util/splice-changes-into-string.ts b/packages/tailwindcss-language-service/src/util/splice-changes-into-string.ts index e1e6f168..ec601708 100644 --- a/packages/tailwindcss-language-service/src/util/splice-changes-into-string.ts +++ b/packages/tailwindcss-language-service/src/util/splice-changes-into-string.ts @@ -8,7 +8,7 @@ export interface StringChange { * Apply the changes to the string such that a change in the length * of the string does not break the indexes of the subsequent changes. */ -export function spliceChangesIntoString(str: string, changes: StringChange[]) { +export function spliceChangesIntoString(str: string, changes: StringChange[]): string { // If there are no changes, return the original string if (!changes[0]) return str diff --git a/packages/tailwindcss-language-service/src/util/test-utils.ts b/packages/tailwindcss-language-service/src/util/test-utils.ts index ce66ecaf..9a01cf9a 100644 --- a/packages/tailwindcss-language-service/src/util/test-utils.ts +++ b/packages/tailwindcss-language-service/src/util/test-utils.ts @@ -1,15 +1,15 @@ -import { createState, getDefaultTailwindSettings, Settings } from './state' +import { createState, getDefaultTailwindSettings, Settings, State } from './state' import { TextDocument } from 'vscode-languageserver-textdocument' import type { DeepPartial } from '../types' -import dedent from 'dedent' +import dedent, { type Dedent } from 'dedent' -export const js = dedent -export const jsx = dedent -export const ts = dedent -export const tsx = dedent -export const css = dedent -export const html = dedent -export const pug = dedent +export const js: Dedent = dedent +export const jsx: Dedent = dedent +export const ts: Dedent = dedent +export const tsx: Dedent = dedent +export const css: Dedent = dedent +export const html: Dedent = dedent +export const pug: Dedent = dedent export function createDocument({ name, @@ -21,7 +21,7 @@ export function createDocument({ lang: string content: string | string[] settings?: DeepPartial -}) { +}): { doc: TextDocument; state: State } { let doc = TextDocument.create( `file://${name}`, lang, diff --git a/packages/tailwindcss-language-service/src/util/v4/ast.ts b/packages/tailwindcss-language-service/src/util/v4/ast.ts index 452f35ff..a60d7934 100644 --- a/packages/tailwindcss-language-service/src/util/v4/ast.ts +++ b/packages/tailwindcss-language-service/src/util/v4/ast.ts @@ -22,7 +22,7 @@ export function visit( nodes: AstNode[], cb: (node: AstNode, path: AstNode[]) => void, path: AstNode[] = [], -) { +): void { for (let child of nodes) { path = [...path, child] cb(child, path) diff --git a/packages/tailwindcss-language-service/tsconfig.json b/packages/tailwindcss-language-service/tsconfig.json index 46eb230c..10bf6a9f 100644 --- a/packages/tailwindcss-language-service/tsconfig.json +++ b/packages/tailwindcss-language-service/tsconfig.json @@ -16,6 +16,7 @@ "moduleResolution": "Bundler", "skipLibCheck": true, "jsx": "react", - "esModuleInterop": true + "esModuleInterop": true, + "isolatedDeclarations": true } }