@@ -146,39 +146,45 @@ export function substituteAtApply(ast: AstNode[], designSystem: DesignSystem) {
146146 visit ( node )
147147 }
148148
149- // Substitute the `@apply` at-rules in order
150- walk ( sorted , ( node , { replaceWith } ) => {
151- if ( node . kind !== 'at-rule' || node . name !== '@apply' ) return
152- let candidates = node . params . split ( / \s + / g)
153-
154- // Replace the `@apply` rule with the actual utility classes
155- {
156- // Parse the candidates to an AST that we can replace the `@apply` rule
157- // with.
158- let candidateAst = compileCandidates ( candidates , designSystem , {
159- onInvalidCandidate : ( candidate ) => {
160- throw new Error ( `Cannot apply unknown utility class: ${ candidate } ` )
161- } ,
162- } ) . astNodes
163-
164- // Collect the nodes to insert in place of the `@apply` rule. When a rule
165- // was used, we want to insert its children instead of the rule because we
166- // don't want the wrapping selector.
167- let newNodes : AstNode [ ] = [ ]
168- for ( let candidateNode of candidateAst ) {
169- if ( candidateNode . kind === 'rule' ) {
170- for ( let child of candidateNode . nodes ) {
171- newNodes . push ( child )
149+ // Substitute the `@apply` at-rules in order. Note that the list is going to
150+ // be flattened so we do not have to recursively walk over child rules
151+ for ( let parent of sorted ) {
152+ if ( ! ( 'nodes' in parent ) ) continue
153+
154+ for ( let i = 0 ; i < parent . nodes . length ; i ++ ) {
155+ let node = parent . nodes [ i ]
156+ if ( node . kind !== 'at-rule' || node . name !== '@apply' ) continue
157+
158+ let candidates = node . params . split ( / \s + / g)
159+
160+ // Replace the `@apply` rule with the actual utility classes
161+ {
162+ // Parse the candidates to an AST that we can replace the `@apply` rule
163+ // with.
164+ let candidateAst = compileCandidates ( candidates , designSystem , {
165+ onInvalidCandidate : ( candidate ) => {
166+ throw new Error ( `Cannot apply unknown utility class: ${ candidate } ` )
167+ } ,
168+ } ) . astNodes
169+
170+ // Collect the nodes to insert in place of the `@apply` rule. When a rule
171+ // was used, we want to insert its children instead of the rule because we
172+ // don't want the wrapping selector.
173+ let newNodes : AstNode [ ] = [ ]
174+ for ( let candidateNode of candidateAst ) {
175+ if ( candidateNode . kind === 'rule' ) {
176+ for ( let child of candidateNode . nodes ) {
177+ newNodes . push ( child )
178+ }
179+ } else {
180+ newNodes . push ( candidateNode )
172181 }
173- } else {
174- newNodes . push ( candidateNode )
175182 }
176- }
177183
178- replaceWith ( newNodes )
184+ parent . nodes . splice ( i , 1 , ...newNodes )
185+ }
179186 }
180- } )
181-
187+ }
182188 return features
183189}
184190
0 commit comments