Skip to content

Commit 8a28f81

Browse files
Merge branch 'main' into feat/improved-utility-completion-details
2 parents a567d75 + 0e16829 commit 8a28f81

File tree

16 files changed

+556
-854
lines changed

16 files changed

+556
-854
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,13 @@ jobs:
2727
run: pnpm install
2828

2929
- name: Run syntax tests
30-
run: |
31-
cd packages/tailwindcss-language-syntax &&
32-
pnpm run build &&
33-
pnpm run test
30+
working-directory: packages/tailwindcss-language-syntax
31+
run: pnpm run build && pnpm run test
3432

3533
- name: Run service tests
36-
run: |
37-
cd packages/tailwindcss-language-service &&
38-
pnpm run build &&
39-
pnpm run test
34+
working-directory: packages/tailwindcss-language-service
35+
run: pnpm run build && pnpm run test
4036

41-
- name: Run tests
42-
run: |
43-
cd packages/tailwindcss-language-server &&
44-
pnpm run build &&
45-
pnpm run test
37+
- name: Run server tests
38+
working-directory: packages/tailwindcss-language-server
39+
run: pnpm run build && pnpm run test

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"@npmcli/package-json": "^5.0.0",
66
"@types/culori": "^2.1.0",
77
"culori": "^4.0.1",
8-
"esbuild": "^0.25.0",
8+
"esbuild": "^0.25.5",
99
"minimist": "^1.2.8",
1010
"prettier": "^3.2.5",
1111
"semver": "^7.7.1"

packages/tailwindcss-language-server/package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
"dlv": "1.1.3",
7575
"dset": "3.1.4",
7676
"enhanced-resolve": "^5.16.1",
77-
"esbuild": "^0.25.0",
77+
"esbuild": "^0.25.5",
7878
"find-up": "5.0.0",
7979
"jiti": "^2.3.3",
8080
"klona": "2.0.4",
@@ -83,7 +83,7 @@
8383
"normalize-path": "3.0.0",
8484
"picomatch": "^4.0.1",
8585
"pkg-up": "3.1.0",
86-
"postcss": "8.4.31",
86+
"postcss": "8.5.4",
8787
"postcss-import": "^16.1.0",
8888
"postcss-load-config": "3.0.1",
8989
"postcss-selector-parser": "6.0.2",
@@ -96,8 +96,9 @@
9696
"tsconfck": "^3.1.4",
9797
"tsconfig-paths": "^4.2.0",
9898
"typescript": "5.8.3",
99-
"vite-tsconfig-paths": "^4.3.1",
100-
"vitest": "^3.0.9",
99+
"vite": "^6.3.5",
100+
"vite-tsconfig-paths": "^5.1.4",
101+
"vitest": "^3.2.1",
101102
"vscode-css-languageservice": "6.3.6",
102103
"vscode-jsonrpc": "8.2.0",
103104
"vscode-languageclient": "8.1.0",

packages/tailwindcss-language-server/src/tw.ts

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,32 +122,68 @@ export class TW {
122122
await this.initPromise
123123
}
124124

125+
private validateFolderUri(uri: URI): boolean {
126+
if (uri.scheme !== 'file') {
127+
console.warn(
128+
`The workspace folder [${uri.toString()}] will be ignored: it does not use the file scheme.`,
129+
)
130+
return false
131+
}
132+
133+
if (uri.fsPath === '/' || uri.fsPath === '\\\\') {
134+
console.warn(
135+
`The workspace folder [${uri.toString()}] will be ignored: it starts at the root of the filesystem which is most likely an error.`,
136+
)
137+
return false
138+
}
139+
140+
return true
141+
}
142+
125143
private getWorkspaceFolders(): WorkspaceFolder[] {
126144
if (this.initializeParams.workspaceFolders?.length) {
127-
return this.initializeParams.workspaceFolders.map((folder) => ({
128-
uri: URI.parse(folder.uri).fsPath,
129-
name: folder.name,
130-
}))
145+
return this.initializeParams.workspaceFolders.flatMap((folder) => {
146+
let uri = URI.parse(folder.uri)
147+
148+
if (!this.validateFolderUri(uri)) return []
149+
150+
return [
151+
{
152+
uri: uri.fsPath,
153+
name: folder.name,
154+
},
155+
]
156+
})
131157
}
132158

133159
if (this.initializeParams.rootUri) {
160+
let uri = URI.parse(this.initializeParams.rootUri)
161+
162+
if (!this.validateFolderUri(uri)) return []
163+
134164
return [
135165
{
136-
uri: URI.parse(this.initializeParams.rootUri).fsPath,
166+
uri: uri.fsPath,
137167
name: 'Root',
138168
},
139169
]
140170
}
141171

142172
if (this.initializeParams.rootPath) {
173+
let uri = URI.file(this.initializeParams.rootPath)
174+
175+
if (!this.validateFolderUri(uri)) return []
176+
143177
return [
144178
{
145-
uri: URI.file(this.initializeParams.rootPath).fsPath,
179+
uri: uri.fsPath,
146180
name: 'Root',
147181
},
148182
]
149183
}
150184

185+
console.warn(`No workspace folders detected`)
186+
151187
return []
152188
}
153189

@@ -976,6 +1012,15 @@ export class TW {
9761012
let matchedPriority: number = Infinity
9771013

9781014
let uri = URI.parse(document.uri)
1015+
1016+
if (uri.scheme !== 'file') {
1017+
console.debug(`Cannot get project for a non-file document. They are unsupported.`, {
1018+
uri: uri.toString(),
1019+
})
1020+
1021+
return null
1022+
}
1023+
9791024
let fsPath = uri.fsPath
9801025
let normalPath = uri.path
9811026

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { defineConfig } from 'vitest/config'
2+
import tsconfigPaths from 'vite-tsconfig-paths'
3+
4+
export default defineConfig({
5+
test: {
6+
testTimeout: 15000,
7+
css: true,
8+
silent: 'passed-only',
9+
},
10+
11+
plugins: [
12+
tsconfigPaths(),
13+
{
14+
name: 'force-inline-css',
15+
enforce: 'pre',
16+
resolveId(id) {
17+
if (!id.includes('index.css')) return
18+
if (id.includes('?raw')) return
19+
return this.resolve(`${id}?raw`)
20+
},
21+
},
22+
],
23+
})

packages/tailwindcss-language-server/vitest.config.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

packages/tailwindcss-language-service/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"dset": "3.1.4",
3030
"line-column": "1.0.2",
3131
"moo": "0.5.1",
32-
"postcss": "8.4.31",
32+
"postcss": "8.5.4",
3333
"postcss-selector-parser": "6.0.2",
3434
"postcss-value-parser": "4.2.0",
3535
"semver": "7.7.1",
@@ -48,11 +48,12 @@
4848
"@types/node": "^18.19.33",
4949
"@types/stringify-object": "^4.0.5",
5050
"dedent": "^1.5.3",
51-
"esbuild": "^0.25.0",
51+
"esbuild": "^0.25.5",
5252
"esbuild-node-externals": "^1.9.0",
5353
"minimist": "^1.2.8",
5454
"tslib": "2.2.0",
5555
"typescript": "^5.8.3",
56-
"vitest": "^3.0.9"
56+
"vite": "^6.3.5",
57+
"vitest": "^3.2.1"
5758
}
5859
}

packages/tailwindcss-language-service/src/completionProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2362,7 +2362,7 @@ export async function resolveCompletionItem(
23622362
decls = decls.filter(isOtherDecl)
23632363
}
23642364

2365-
item.detail = await jit.stringifyDecls(state, postcss.rule({ nodes: decls }))
2365+
item.detail = await jit.stringifyDecls(state, postcss.rule({ selectors: [], nodes: decls }))
23662366
} else {
23672367
item.detail = `${rules.length} rules`
23682368
}

packages/tailwindcss-language-service/src/util/rewriting/index.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { expect, test } from 'vitest'
22
import {
33
addThemeValues,
44
evaluateExpression,
5+
inlineThemeValues,
56
replaceCssCalc,
67
replaceCssVarsWithFallbacks,
78
} from './index'
@@ -124,6 +125,42 @@ test('recursive theme replacements', () => {
124125
)
125126
})
126127

128+
test('recursive theme replacements (inlined)', () => {
129+
let map = new Map<string, string>([
130+
['--color-a', 'var(--color-a)'],
131+
['--color-b', 'rgb(var(--color-b))'],
132+
['--color-c', 'rgb(var(--channel) var(--channel) var(--channel))'],
133+
['--channel', '255'],
134+
135+
['--color-d', 'rgb(var(--indirect) var(--indirect) var(--indirect))'],
136+
['--indirect', 'var(--channel)'],
137+
['--channel', '255'],
138+
139+
['--mutual-a', 'calc(var(--mutual-b) * 1)'],
140+
['--mutual-b', 'calc(var(--mutual-a) + 1)'],
141+
])
142+
143+
let state: State = {
144+
enabled: true,
145+
designSystem: {
146+
theme: { prefix: null } as any,
147+
resolveThemeValue: (name) => map.get(name) ?? null,
148+
} as DesignSystem,
149+
}
150+
151+
expect(inlineThemeValues('var(--color-a)', state)).toBe('var(--color-a)')
152+
expect(inlineThemeValues('var(--color-b)', state)).toBe('rgb(var(--color-b))')
153+
expect(inlineThemeValues('var(--color-c)', state)).toBe('rgb(255 255 255)')
154+
155+
// This one is wrong but fixing it without breaking the infinite recursion guard is complex
156+
expect(inlineThemeValues('var(--color-d)', state)).toBe(
157+
'rgb(255 var(--indirect) var(--indirect))',
158+
)
159+
160+
expect(inlineThemeValues('var(--mutual-a)', state)).toBe('calc(calc(var(--mutual-a) + 1) * 1)')
161+
expect(inlineThemeValues('var(--mutual-b)', state)).toBe('calc(calc(var(--mutual-b) * 1) + 1)')
162+
})
163+
127164
test('Evaluating CSS calc expressions', () => {
128165
expect(replaceCssCalc('calc(1px + 1px)', (node) => evaluateExpression(node.value))).toBe('2px')
129166
expect(replaceCssCalc('calc(1px * 4)', (node) => evaluateExpression(node.value))).toBe('4px')

packages/tailwindcss-language-service/src/util/rewriting/inline-theme-values.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,20 @@ import { replaceCssVars, replaceCssCalc } from './replacements'
77
export function inlineThemeValues(css: string, state: State): string {
88
if (!state.designSystem) return css
99

10+
let seen = new Set<string>()
11+
1012
css = replaceCssCalc(css, (expr) => {
1113
let inlined = replaceCssVars(expr.value, {
1214
replace({ name, fallback }) {
1315
if (!name.startsWith('--')) return null
1416

17+
// TODO: This isn't quite right as we might skip expanding a variable
18+
// that should be expanded
19+
if (seen.has(name)) return null
20+
1521
let value = resolveVariableValue(state.designSystem, name)
1622
if (value === null) return fallback
23+
if (value.includes('var(')) seen.add(name)
1724

1825
return value
1926
},
@@ -26,8 +33,13 @@ export function inlineThemeValues(css: string, state: State): string {
2633
replace({ name, fallback }) {
2734
if (!name.startsWith('--')) return null
2835

36+
// TODO: This isn't quite right as we might skip expanding a variable
37+
// that should be expanded
38+
if (seen.has(name)) return null
39+
2940
let value = resolveVariableValue(state.designSystem, name)
3041
if (value === null) return fallback
42+
if (value.includes('var(')) seen.add(name)
3143

3244
return value
3345
},

packages/tailwindcss-language-service/vitest.config.ts renamed to packages/tailwindcss-language-service/vitest.config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import { defineConfig } from 'vitest/config'
33
export default defineConfig({
44
test: {
55
testTimeout: 15000,
6+
silent: 'passed-only',
67
},
78
})

packages/tailwindcss-language-syntax/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"devDependencies": {
1010
"@types/node": "^18.19.33",
1111
"dedent": "^1.5.3",
12-
"vitest": "^3.1.4",
12+
"vitest": "^3.2.1",
1313
"vscode-oniguruma": "^2.0.1",
1414
"vscode-textmate": "^9.2.0"
1515
}

packages/tailwindcss-language-syntax/vitest.config.ts renamed to packages/tailwindcss-language-syntax/vitest.config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import { defineConfig } from 'vitest/config'
33
export default defineConfig({
44
test: {
55
testTimeout: 15000,
6+
silent: 'passed-only',
67
},
78
})

packages/vscode-tailwindcss/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Prerelease
44

55
- Bump bundled CSS language service ([#1395](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1395))
6+
- Fix infinite loop when resolving completion details with recursive theme keys ([#1400](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1400))
67
- Simplify completion details for more utilities ([#1397](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1397))
78

89
## 0.14.20

packages/vscode-tailwindcss/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@
382382
"@vscode/vsce": "2.21.1",
383383
"braces": "3.0.3",
384384
"color-name": "1.1.4",
385-
"concurrently": "7.0.0",
386-
"esbuild": "^0.25.0",
385+
"concurrently": "9.1.2",
386+
"esbuild": "^0.25.5",
387387
"minimist": "^1.2.8",
388388
"move-file-cli": "3.0.0",
389389
"normalize-path": "3.0.0",

0 commit comments

Comments
 (0)