Skip to content

Commit 87107c9

Browse files
committed
Collect Scopes about @import
1 parent 24d52f0 commit 87107c9

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

packages/tailwindcss-language-service/src/scopes/analyze.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
ScopeAtRule,
66
ScopeClassList,
77
ScopeClassName,
8+
ScopeAtImport,
89
} from './scope'
910
import { ScopeTree } from './tree'
1011
import { getDocumentLanguages, LanguageBoundary } from '../util/getLanguageBoundaries'
@@ -235,5 +236,87 @@ function* analyzeAtRule(
235236
})
236237
}
237238

239+
// `@import` statements are special
240+
else if (name === '@import') {
241+
let importScope: ScopeAtImport = {
242+
kind: 'css.at-rule.import',
243+
children: [],
244+
source: {
245+
scope: overallSpan,
246+
url: null,
247+
sourceUrl: null,
248+
},
249+
}
250+
251+
scope.children.push(importScope)
252+
253+
let start = 0
254+
255+
for (let part of parts) {
256+
let offset = start
257+
let length = part.length + 1
258+
let type: string | null = null
259+
let quotable = true
260+
261+
if (part.startsWith('url(')) {
262+
type = 'url'
263+
quotable = true
264+
part = part.slice(4)
265+
offset += 4
266+
267+
if (part.endsWith(')')) {
268+
part = part.slice(0, -1)
269+
}
270+
}
271+
272+
//
273+
else if (part.startsWith('source(')) {
274+
type = 'source-url'
275+
quotable = true
276+
part = part.slice(7)
277+
offset += 7
278+
279+
if (part.endsWith(')')) {
280+
part = part.slice(0, -1)
281+
}
282+
}
283+
284+
if (quotable && part.startsWith('"')) {
285+
type ??= 'url'
286+
part = part.slice(1)
287+
offset += 1
288+
289+
if (part.endsWith('"')) {
290+
part = part.slice(0, -1)
291+
}
292+
}
293+
294+
//
295+
else if (quotable && part.startsWith("'")) {
296+
type ??= 'url'
297+
part = part.slice(1)
298+
offset += 1
299+
300+
if (part.endsWith("'")) {
301+
part = part.slice(0, -1)
302+
}
303+
}
304+
305+
if (type === 'url') {
306+
importScope.source.url = [paramsSpan[0] + offset, paramsSpan[0] + offset + part.length]
307+
}
308+
309+
//
310+
else if (type === 'source-url') {
311+
importScope.source.sourceUrl = [
312+
paramsSpan[0] + offset,
313+
paramsSpan[0] + offset + part.length,
314+
]
315+
}
316+
317+
start += length
318+
}
319+
}
320+
238321
yield scope
239322
}

packages/tailwindcss-language-service/src/scopes/scope.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,39 @@ export interface ScopeAtUtility {
233233
}
234234
}
235235

236+
/**
237+
* Text that represents a single class
238+
*
239+
* ```
240+
* @import "./some-file.css";
241+
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
242+
* ````
243+
*/
244+
export interface ScopeAtImport {
245+
kind: 'css.at-rule.import'
246+
children: AnyScope[]
247+
248+
source: {
249+
scope: Span
250+
251+
// Marks the url of an import statement
252+
// @import "./some-file.css";
253+
// ^^^^^^^^^^^^^^^
254+
// @reference "./some-file.css";
255+
// ^^^^^^^^^^^^^^^
256+
// @import url("./some-file.css");
257+
// ^^^^^^^^^^^^^^^^^
258+
url: Span | null
259+
260+
// Marks an import statement's source url
261+
// @import "./some-file.css" source("./foo");
262+
// ^^^^^
263+
// @import "./some-file.css" source(none);
264+
// ^^^^
265+
sourceUrl: Span | null
266+
}
267+
}
268+
236269
export type ScopeKind = keyof ScopeMap
237270
export type Scope<K extends ScopeKind> = ScopeMap[K]
238271
export type AnyScope = ScopeMap[ScopeKind]
@@ -245,4 +278,5 @@ type ScopeMap = {
245278
'class.name': ScopeClassName
246279
'css.at-rule': ScopeAtRule
247280
'css.at-rule.utility': ScopeAtUtility
281+
'css.at-rule.import': ScopeAtImport
248282
}

0 commit comments

Comments
 (0)