Skip to content

Commit 1e718f9

Browse files
committed
defer analysis, address TODO
1 parent 3f73102 commit 1e718f9

File tree

4 files changed

+52
-44
lines changed

4 files changed

+52
-44
lines changed

packages/svelte/src/compiler/phases/1-parse/read/style.js

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -213,34 +213,6 @@ function read_selector(parser, inside_pseudo_class = false) {
213213
/** @type {import('#compiler').Css.RelativeSelector} */
214214
let relative_selector = create_selector(null, parser.index);
215215

216-
/**
217-
*
218-
* @param {import('#compiler').Css.RelativeSelector} node
219-
* @param {number} end
220-
*/
221-
const flush = (node, end) => {
222-
node.metadata.is_global =
223-
node.selectors.length >= 1 &&
224-
node.selectors[0].type === 'PseudoClassSelector' &&
225-
node.selectors[0].name === 'global' &&
226-
node.selectors.every(
227-
(selector) =>
228-
selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector'
229-
);
230-
231-
if (node.selectors.length === 1) {
232-
const first = node.selectors[0];
233-
node.metadata.is_host = first.type === 'PseudoClassSelector' && first.name === 'host';
234-
}
235-
236-
node.metadata.is_root = !!node.selectors.find(
237-
(child) => child.type === 'PseudoClassSelector' && child.name === 'root'
238-
);
239-
240-
relative_selector.end = end;
241-
children.push(relative_selector);
242-
};
243-
244216
while (parser.index < parser.template.length) {
245217
let start = parser.index;
246218

@@ -252,7 +224,8 @@ function read_selector(parser, inside_pseudo_class = false) {
252224
error(start, 'invalid-css-selector');
253225
}
254226
} else {
255-
flush(relative_selector, start);
227+
relative_selector.end = start;
228+
children.push(relative_selector);
256229
}
257230

258231
// ...and start a new one
@@ -398,17 +371,16 @@ function read_selector(parser, inside_pseudo_class = false) {
398371
// rewind, so we know whether to continue building the selector list
399372
parser.index = index;
400373

401-
flush(relative_selector, index);
374+
relative_selector.end = index;
375+
children.push(relative_selector);
402376

403377
return {
404378
type: 'ComplexSelector',
405379
start: list_start,
406380
end: index,
407381
children,
408382
metadata: {
409-
used: children.every(
410-
({ metadata }) => metadata.is_global || metadata.is_host || metadata.is_root
411-
)
383+
used: false
412384
}
413385
};
414386
}

packages/svelte/src/compiler/phases/2-analyze/validation/css.js renamed to packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
import { error } from '../../../errors.js';
22
import { is_keyframes_node } from '../../css.js';
3+
import { merge } from '../../visitors.js';
4+
5+
/**
6+
* @typedef {import('zimmerframe').Visitors<
7+
* import('#compiler').Css.Node,
8+
* NonNullable<import('../../types.js').ComponentAnalysis['css']>
9+
* >} Visitors
10+
*/
311

412
/** @param {import('#compiler').Css.RelativeSelector} relative_selector */
513
function is_global(relative_selector) {
@@ -15,21 +23,47 @@ function is_global(relative_selector) {
1523
);
1624
}
1725

18-
// TODO rename, this isn't just validation any more
19-
/**
20-
* @type {import('zimmerframe').Visitors<
21-
* import('#compiler').Css.Node,
22-
* NonNullable<import('../../types.js').ComponentAnalysis['css']>
23-
* >}
24-
*/
25-
export const validation_css = {
26+
/** @type {Visitors} */
27+
const analysis = {
2628
Atrule(node, context) {
2729
if (is_keyframes_node(node)) {
2830
if (!node.prelude.startsWith('-global-')) {
2931
context.state.keyframes.push(node.prelude);
3032
}
3133
}
3234
},
35+
ComplexSelector(node, context) {
36+
context.next(); // analyse relevant selectors first
37+
38+
node.metadata.used = node.children.every(
39+
({ metadata }) => metadata.is_global || metadata.is_host || metadata.is_root
40+
);
41+
},
42+
RelativeSelector(node, context) {
43+
node.metadata.is_global =
44+
node.selectors.length >= 1 &&
45+
node.selectors[0].type === 'PseudoClassSelector' &&
46+
node.selectors[0].name === 'global' &&
47+
node.selectors.every(
48+
(selector) =>
49+
selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector'
50+
);
51+
52+
if (node.selectors.length === 1) {
53+
const first = node.selectors[0];
54+
node.metadata.is_host = first.type === 'PseudoClassSelector' && first.name === 'host';
55+
}
56+
57+
node.metadata.is_root = !!node.selectors.find(
58+
(child) => child.type === 'PseudoClassSelector' && child.name === 'root'
59+
);
60+
61+
context.next();
62+
}
63+
};
64+
65+
/** @type {Visitors} */
66+
const validation = {
3367
ComplexSelector(node, context) {
3468
// ensure `:global(...)` is not used in the middle of a selector
3569
{
@@ -86,3 +120,5 @@ export const validation_css = {
86120
}
87121
}
88122
};
123+
124+
export const css_visitors = merge(analysis, validation);

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import { regex_starts_with_newline } from '../patterns.js';
2020
import { create_attribute, is_element_node } from '../nodes.js';
2121
import { DelegatedEvents, namespace_svg } from '../../../constants.js';
2222
import { should_proxy_or_freeze } from '../3-transform/client/utils.js';
23-
import { validation_css } from './validation/css.js';
24-
import { prune } from './css/index.js';
23+
import { css_visitors } from './css/css-analyze.js';
24+
import { prune } from './css/css-prune.js';
2525
import { hash } from './utils.js';
2626

2727
/**
@@ -461,7 +461,7 @@ export function analyze_component(root, options) {
461461

462462
if (analysis.css.ast) {
463463
// validate
464-
walk(analysis.css.ast, analysis.css, validation_css);
464+
walk(analysis.css.ast, analysis.css, css_visitors);
465465

466466
// mark nodes as scoped/unused/empty etc
467467
for (const element of analysis.elements) {

0 commit comments

Comments
 (0)