Skip to content

Commit bd9b34a

Browse files
committed
Fix crash when mixin @import with @use
Fixes #2588
1 parent a42380f commit bd9b34a

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

lib/src/visitor/async_evaluate.dart

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ final class _EvaluateVisitor
208208

209209
ModifiableCssParentNode? __parent;
210210

211+
/// The original parent node for a stylesheet that was loaded with @import.
212+
///
213+
/// This value is only set when a file uses `@import` in combination with
214+
/// non-built-in Sass modules.
215+
ModifiableCssParentNode? _importParent;
216+
211217
/// The name of the current declaration parent.
212218
String? _declarationName;
213219

@@ -1321,7 +1327,12 @@ final class _EvaluateVisitor
13211327
}
13221328

13231329
Future<Value?> visitDeclaration(Declaration node) async {
1324-
if (_styleRule == null && !_inUnknownAtRule && !_inKeyframes) {
1330+
// If a stylesheet is @imported inside a style rule, declarations from that
1331+
// imported sheet are parented by the outer style rule.
1332+
var parent = _parent.parent == null ? _importParent : _parent;
1333+
1334+
if ((_styleRule == null && !_inUnknownAtRule && !_inKeyframes) ||
1335+
parent == null) {
13251336
throw _exception(
13261337
"Declarations may only be used within style rules.",
13271338
node.span,
@@ -1334,14 +1345,14 @@ final class _EvaluateVisitor
13341345
);
13351346
}
13361347

1337-
var siblings = _parent.parent!.children;
1348+
var siblings = parent.parent?.children ?? [];
13381349
var interleavedRules = <CssStyleRule>[];
1339-
if (siblings.last != _parent &&
1340-
// Reproduce this condition from [_warn] so that we don't add anything to
1341-
// [interleavedRules] for declarations in dependencies.
1350+
if (siblings.last != parent &&
1351+
// Reproduce this condition from [_warn] so that we don't add anything
1352+
// to [interleavedRules] for declarations in dependencies.
13421353
!(_quietDeps && _inDependency)) {
13431354
loop:
1344-
for (var sibling in siblings.skip(siblings.indexOf(_parent) + 1)) {
1355+
for (var sibling in siblings.skip(siblings.indexOf(parent) + 1)) {
13451356
switch (sibling) {
13461357
case CssComment():
13471358
continue loop;
@@ -1387,7 +1398,7 @@ final class _EvaluateVisitor
13871398
_isEmptyList(value) ||
13881399
// Custom properties are allowed to have empty values, per spec.
13891400
name.value.startsWith('--')) {
1390-
_parent.addChild(
1401+
parent.addChild(
13911402
ModifiableCssDeclaration(
13921403
name,
13931404
CssValue(value, expression.span),
@@ -1895,6 +1906,7 @@ final class _EvaluateVisitor
18951906
_stylesheet = stylesheet;
18961907
if (loadsUserDefinedModules) {
18971908
_root = ModifiableCssStylesheet(stylesheet.span);
1909+
_importParent = _parent;
18981910
_parent = _root;
18991911
_endOfImports = 0;
19001912
_outOfOrderImports = null;
@@ -1915,6 +1927,7 @@ final class _EvaluateVisitor
19151927
if (loadsUserDefinedModules) {
19161928
_root = oldRoot;
19171929
_parent = oldParent;
1930+
_importParent = null;
19181931
_endOfImports = oldEndOfImports;
19191932
_outOfOrderImports = oldOutOfOrderImports;
19201933
}

lib/src/visitor/evaluate.dart

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_evaluate.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: a3068d04660dd2bed34b884aa6e1a21d423dc4e5
8+
// Checksum: 25e98f7f4a04108e924c63b63b1db844637a66e0
99
//
1010
// ignore_for_file: unused_import
1111

@@ -216,6 +216,9 @@ final class _EvaluateVisitor
216216

217217
ModifiableCssParentNode? __parent;
218218

219+
/// The original parent node for a stylesheet that was loaded with @import.
220+
ModifiableCssParentNode? _importParent;
221+
219222
/// The name of the current declaration parent.
220223
String? _declarationName;
221224

@@ -1329,7 +1332,12 @@ final class _EvaluateVisitor
13291332
}
13301333

13311334
Value? visitDeclaration(Declaration node) {
1332-
if (_styleRule == null && !_inUnknownAtRule && !_inKeyframes) {
1335+
// If a stylesheet is @imported inside a style rule, declarations from that
1336+
// imported sheet are parented by the outer style rule.
1337+
var parent = _parent.parent == null ? _importParent : _parent;
1338+
1339+
if ((_styleRule == null && !_inUnknownAtRule && !_inKeyframes) ||
1340+
parent == null) {
13331341
throw _exception(
13341342
"Declarations may only be used within style rules.",
13351343
node.span,
@@ -1342,14 +1350,14 @@ final class _EvaluateVisitor
13421350
);
13431351
}
13441352

1345-
var siblings = _parent.parent!.children;
1353+
var siblings = parent.parent?.children ?? [];
13461354
var interleavedRules = <CssStyleRule>[];
1347-
if (siblings.last != _parent &&
1348-
// Reproduce this condition from [_warn] so that we don't add anything to
1349-
// [interleavedRules] for declarations in dependencies.
1355+
if (siblings.last != parent &&
1356+
// Reproduce this condition from [_warn] so that we don't add anything
1357+
// to [interleavedRules] for declarations in dependencies.
13501358
!(_quietDeps && _inDependency)) {
13511359
loop:
1352-
for (var sibling in siblings.skip(siblings.indexOf(_parent) + 1)) {
1360+
for (var sibling in siblings.skip(siblings.indexOf(parent) + 1)) {
13531361
switch (sibling) {
13541362
case CssComment():
13551363
continue loop;
@@ -1395,7 +1403,7 @@ final class _EvaluateVisitor
13951403
_isEmptyList(value) ||
13961404
// Custom properties are allowed to have empty values, per spec.
13971405
name.value.startsWith('--')) {
1398-
_parent.addChild(
1406+
parent.addChild(
13991407
ModifiableCssDeclaration(
14001408
name,
14011409
CssValue(value, expression.span),
@@ -1903,6 +1911,7 @@ final class _EvaluateVisitor
19031911
_stylesheet = stylesheet;
19041912
if (loadsUserDefinedModules) {
19051913
_root = ModifiableCssStylesheet(stylesheet.span);
1914+
_importParent = _parent;
19061915
_parent = _root;
19071916
_endOfImports = 0;
19081917
_outOfOrderImports = null;
@@ -1923,6 +1932,7 @@ final class _EvaluateVisitor
19231932
if (loadsUserDefinedModules) {
19241933
_root = oldRoot;
19251934
_parent = oldParent;
1935+
_importParent = null;
19261936
_endOfImports = oldEndOfImports;
19271937
_outOfOrderImports = oldOutOfOrderImports;
19281938
}

0 commit comments

Comments
 (0)