1
1
import { Features } from '..'
2
2
import { styleRule , toCss , walk , WalkAction , type AstNode } from '../ast'
3
3
import type { DesignSystem } from '../design-system'
4
+ import type { SourceLocation } from '../source-maps/source'
4
5
import { segment } from '../utils/segment'
5
6
import { applyConfigToTheme } from './apply-config-to-theme'
6
7
import { applyKeyframesToTheme } from './apply-keyframes-to-theme'
@@ -38,9 +39,16 @@ export async function applyCompatibilityHooks({
38
39
sources : { base : string ; pattern : string ; negated : boolean } [ ]
39
40
} ) {
40
41
let features = Features . None
41
- let pluginPaths : [ { id : string ; base : string ; reference : boolean } , CssPluginOptions | null ] [ ] =
42
- [ ]
43
- let configPaths : { id : string ; base : string ; reference : boolean } [ ] = [ ]
42
+ let pluginPaths : [
43
+ { id : string ; base : string ; reference : boolean ; src : SourceLocation | undefined } ,
44
+ CssPluginOptions | null ,
45
+ ] [ ] = [ ]
46
+ let configPaths : {
47
+ id : string
48
+ base : string
49
+ reference : boolean
50
+ src : SourceLocation | undefined
51
+ } [ ] = [ ]
44
52
45
53
walk ( ast , ( node , { parent, replaceWith, context } ) => {
46
54
if ( node . kind !== 'at-rule' ) return
@@ -100,7 +108,12 @@ export async function applyCompatibilityHooks({
100
108
}
101
109
102
110
pluginPaths . push ( [
103
- { id : pluginPath , base : context . base as string , reference : ! ! context . reference } ,
111
+ {
112
+ id : pluginPath ,
113
+ base : context . base as string ,
114
+ reference : ! ! context . reference ,
115
+ src : node . src ,
116
+ } ,
104
117
Object . keys ( options ) . length > 0 ? options : null ,
105
118
] )
106
119
@@ -123,6 +136,7 @@ export async function applyCompatibilityHooks({
123
136
id : node . params . slice ( 1 , - 1 ) ,
124
137
base : context . base as string ,
125
138
reference : ! ! context . reference ,
139
+ src : node . src ,
126
140
} )
127
141
replaceWith ( [ ] )
128
142
features |= Features . JsPluginCompat
@@ -162,25 +176,27 @@ export async function applyCompatibilityHooks({
162
176
163
177
let [ configs , pluginDetails ] = await Promise . all ( [
164
178
Promise . all (
165
- configPaths . map ( async ( { id, base, reference } ) => {
179
+ configPaths . map ( async ( { id, base, reference, src } ) => {
166
180
let loaded = await loadModule ( id , base , 'config' )
167
181
return {
168
182
path : id ,
169
183
base : loaded . base ,
170
184
config : loaded . module as UserConfig ,
171
185
reference,
186
+ src,
172
187
}
173
188
} ) ,
174
189
) ,
175
190
Promise . all (
176
- pluginPaths . map ( async ( [ { id, base, reference } , pluginOptions ] ) => {
191
+ pluginPaths . map ( async ( [ { id, base, reference, src } , pluginOptions ] ) => {
177
192
let loaded = await loadModule ( id , base , 'plugin' )
178
193
return {
179
194
path : id ,
180
195
base : loaded . base ,
181
196
plugin : loaded . module as Plugin ,
182
197
options : pluginOptions ,
183
198
reference,
199
+ src,
184
200
}
185
201
} ) ,
186
202
) ,
@@ -215,13 +231,15 @@ function upgradeToFullPluginSupport({
215
231
base : string
216
232
config : UserConfig
217
233
reference : boolean
234
+ src : SourceLocation | undefined
218
235
} [ ]
219
236
pluginDetails : {
220
237
path : string
221
238
base : string
222
239
plugin : Plugin
223
240
options : CssPluginOptions | null
224
241
reference : boolean
242
+ src : SourceLocation | undefined
225
243
} [ ]
226
244
} ) {
227
245
let features = Features . None
@@ -231,6 +249,7 @@ function upgradeToFullPluginSupport({
231
249
config : { plugins : [ detail . plugin ] } ,
232
250
base : detail . base ,
233
251
reference : detail . reference ,
252
+ src : detail . src ,
234
253
}
235
254
}
236
255
@@ -239,6 +258,7 @@ function upgradeToFullPluginSupport({
239
258
config : { plugins : [ detail . plugin ( detail . options ) ] } ,
240
259
base : detail . base ,
241
260
reference : detail . reference ,
261
+ src : detail . src ,
242
262
}
243
263
}
244
264
@@ -248,15 +268,32 @@ function upgradeToFullPluginSupport({
248
268
let userConfig = [ ...pluginConfigs , ...configs ]
249
269
250
270
let { resolvedConfig } = resolveConfig ( designSystem , [
251
- { config : createCompatConfig ( designSystem . theme ) , base, reference : true } ,
271
+ { config : createCompatConfig ( designSystem . theme ) , base, reference : true , src : undefined } ,
252
272
...userConfig ,
253
- { config : { plugins : [ darkModePlugin ] } , base, reference : true } ,
273
+ { config : { plugins : [ darkModePlugin ] } , base, reference : true , src : undefined } ,
254
274
] )
255
275
let { resolvedConfig : resolvedUserConfig , replacedThemeKeys } = resolveConfig (
256
276
designSystem ,
257
277
userConfig ,
258
278
)
259
279
280
+ let pluginApiConfig = {
281
+ designSystem,
282
+ ast,
283
+ resolvedConfig,
284
+ featuresRef : {
285
+ set current ( value : number ) {
286
+ features |= value
287
+ } ,
288
+ } ,
289
+ }
290
+
291
+ let sharedPluginApi = buildPluginApi ( {
292
+ ...pluginApiConfig ,
293
+ referenceMode : false ,
294
+ src : undefined ,
295
+ } )
296
+
260
297
// Replace `resolveThemeValue` with a version that is backwards compatible
261
298
// with dot-notation but also aware of any JS theme configurations registered
262
299
// by plugins or JS config files. This is significantly slower than just
@@ -270,7 +307,7 @@ function upgradeToFullPluginSupport({
270
307
return defaultResolveThemeValue ( path , forceInline )
271
308
}
272
309
273
- let resolvedValue = pluginApi . theme ( path , undefined )
310
+ let resolvedValue = sharedPluginApi . theme ( path , undefined )
274
311
275
312
if ( Array . isArray ( resolvedValue ) && resolvedValue . length === 2 ) {
276
313
// When a tuple is returned, return the first element
@@ -285,27 +322,17 @@ function upgradeToFullPluginSupport({
285
322
}
286
323
}
287
324
288
- let pluginApiConfig = {
289
- designSystem,
290
- ast,
291
- resolvedConfig,
292
- featuresRef : {
293
- set current ( value : number ) {
294
- features |= value
295
- } ,
296
- } ,
297
- }
298
-
299
- let pluginApi = buildPluginApi ( { ...pluginApiConfig , referenceMode : false } )
300
- let referenceModePluginApi = undefined
325
+ for ( let { handler, reference, src } of resolvedConfig . plugins ) {
326
+ // Each plugin gets its own instance of the plugin API because nodes added
327
+ // to the AST may need to point to the `@config` or `@plugin` that they
328
+ // originated from
329
+ let api = buildPluginApi ( {
330
+ ...pluginApiConfig ,
331
+ referenceMode : reference ?? false ,
332
+ src,
333
+ } )
301
334
302
- for ( let { handler, reference } of resolvedConfig . plugins ) {
303
- if ( reference ) {
304
- referenceModePluginApi ||= buildPluginApi ( { ...pluginApiConfig , referenceMode : true } )
305
- handler ( referenceModePluginApi )
306
- } else {
307
- handler ( pluginApi )
308
- }
335
+ handler ( api )
309
336
}
310
337
311
338
// Merge the user-configured theme keys into the design system. The compat
0 commit comments