Skip to content

Commit 1672178

Browse files
authored
Fix @at-root bug for common case of built-in use (#1469)
`@at-root` should now work properly in a nested import as long as the only `@use` or `@forward` rules present are for built-in modules. This is a partial but not complete fix for #1347. It's a bit hacky to special case built-in modules here, but since they represent the only real legitimate case for using this combination of features, it lets us fix the bug for this case and avoid the bordering-on-infeasible work of fixing this for user-defined modules.
1 parent f06937e commit 1672178

File tree

6 files changed

+73
-36
lines changed

6 files changed

+73
-36
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.39.1
2+
3+
* Partial fix for a bug where `@at-root` does not work properly in nested
4+
imports that contain `@use` rules. If the only `@use` rules in the nested
5+
import are for built-in modules, `@at-root` should now work properly.
6+
17
## 1.39.0
28

39
### JS API

lib/src/visitor/async_evaluate.dart

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,15 @@ class _EvaluateVisitor
14811481
return;
14821482
}
14831483

1484+
// If only built-in modules are loaded, we still need a separate
1485+
// environment to ensure their namespaces aren't exposed in the outer
1486+
// environment, but we don't need to worry about `@extend`s, so we can
1487+
// add styles directly to the existing stylesheet instead of creating a
1488+
// new one.
1489+
var loadsUserDefinedModules =
1490+
stylesheet.uses.any((rule) => rule.url.scheme != 'sass') ||
1491+
stylesheet.forwards.any((rule) => rule.url.scheme != 'sass');
1492+
14841493
late List<ModifiableCssNode> children;
14851494
var environment = _environment.forImport();
14861495
await _withEnvironment(environment, () async {
@@ -1494,10 +1503,12 @@ class _EvaluateVisitor
14941503
var oldInDependency = _inDependency;
14951504
_importer = result.importer;
14961505
_stylesheet = stylesheet;
1497-
_root = ModifiableCssStylesheet(stylesheet.span);
1498-
_parent = _root;
1499-
_endOfImports = 0;
1500-
_outOfOrderImports = null;
1506+
if (loadsUserDefinedModules) {
1507+
_root = ModifiableCssStylesheet(stylesheet.span);
1508+
_parent = _root;
1509+
_endOfImports = 0;
1510+
_outOfOrderImports = null;
1511+
}
15011512
_inDependency = result.isDependency;
15021513

15031514
// This configuration is only used if it passes through a `@forward`
@@ -1507,7 +1518,7 @@ class _EvaluateVisitor
15071518
}
15081519

15091520
await visitStylesheet(stylesheet);
1510-
children = _addOutOfOrderImports();
1521+
children = loadsUserDefinedModules ? _addOutOfOrderImports() : [];
15111522

15121523
_importer = oldImporter;
15131524
_stylesheet = oldStylesheet;
@@ -1525,18 +1536,21 @@ class _EvaluateVisitor
15251536
var module = environment.toDummyModule();
15261537
_environment.importForwards(module);
15271538

1528-
if (module.transitivelyContainsCss) {
1529-
// If any transitively used module contains extensions, we need to clone
1530-
// all modules' CSS. Otherwise, it's possible that they'll be used or
1531-
// imported from another location that shouldn't have the same extensions
1532-
// applied.
1533-
await _combineCss(module, clone: module.transitivelyContainsExtensions)
1534-
.accept(this);
1535-
}
1539+
if (loadsUserDefinedModules) {
1540+
if (module.transitivelyContainsCss) {
1541+
// If any transitively used module contains extensions, we need to
1542+
// clone all modules' CSS. Otherwise, it's possible that they'll be
1543+
// used or imported from another location that shouldn't have the same
1544+
// extensions applied.
1545+
await _combineCss(module,
1546+
clone: module.transitivelyContainsExtensions)
1547+
.accept(this);
1548+
}
15361549

1537-
var visitor = _ImportedCssVisitor(this);
1538-
for (var child in children) {
1539-
child.accept(visitor);
1550+
var visitor = _ImportedCssVisitor(this);
1551+
for (var child in children) {
1552+
child.accept(visitor);
1553+
}
15401554
}
15411555

15421556
_activeModules.remove(url);

lib/src/visitor/evaluate.dart

Lines changed: 30 additions & 17 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: 2d9c3bb53fc29472f7fbc68d9a3f5b8464f95bc5
8+
// Checksum: 99e7cdfc43a20e2c0827753081db6dcbd914ec75
99
//
1010
// ignore_for_file: unused_import
1111

@@ -1481,6 +1481,15 @@ class _EvaluateVisitor
14811481
return;
14821482
}
14831483

1484+
// If only built-in modules are loaded, we still need a separate
1485+
// environment to ensure their namespaces aren't exposed in the outer
1486+
// environment, but we don't need to worry about `@extend`s, so we can
1487+
// add styles directly to the existing stylesheet instead of creating a
1488+
// new one.
1489+
var loadsUserDefinedModules =
1490+
stylesheet.uses.any((rule) => rule.url.scheme != 'sass') ||
1491+
stylesheet.forwards.any((rule) => rule.url.scheme != 'sass');
1492+
14841493
late List<ModifiableCssNode> children;
14851494
var environment = _environment.forImport();
14861495
_withEnvironment(environment, () {
@@ -1494,10 +1503,12 @@ class _EvaluateVisitor
14941503
var oldInDependency = _inDependency;
14951504
_importer = result.importer;
14961505
_stylesheet = stylesheet;
1497-
_root = ModifiableCssStylesheet(stylesheet.span);
1498-
_parent = _root;
1499-
_endOfImports = 0;
1500-
_outOfOrderImports = null;
1506+
if (loadsUserDefinedModules) {
1507+
_root = ModifiableCssStylesheet(stylesheet.span);
1508+
_parent = _root;
1509+
_endOfImports = 0;
1510+
_outOfOrderImports = null;
1511+
}
15011512
_inDependency = result.isDependency;
15021513

15031514
// This configuration is only used if it passes through a `@forward`
@@ -1507,7 +1518,7 @@ class _EvaluateVisitor
15071518
}
15081519

15091520
visitStylesheet(stylesheet);
1510-
children = _addOutOfOrderImports();
1521+
children = loadsUserDefinedModules ? _addOutOfOrderImports() : [];
15111522

15121523
_importer = oldImporter;
15131524
_stylesheet = oldStylesheet;
@@ -1525,18 +1536,20 @@ class _EvaluateVisitor
15251536
var module = environment.toDummyModule();
15261537
_environment.importForwards(module);
15271538

1528-
if (module.transitivelyContainsCss) {
1529-
// If any transitively used module contains extensions, we need to clone
1530-
// all modules' CSS. Otherwise, it's possible that they'll be used or
1531-
// imported from another location that shouldn't have the same extensions
1532-
// applied.
1533-
_combineCss(module, clone: module.transitivelyContainsExtensions)
1534-
.accept(this);
1535-
}
1539+
if (loadsUserDefinedModules) {
1540+
if (module.transitivelyContainsCss) {
1541+
// If any transitively used module contains extensions, we need to
1542+
// clone all modules' CSS. Otherwise, it's possible that they'll be
1543+
// used or imported from another location that shouldn't have the same
1544+
// extensions applied.
1545+
_combineCss(module, clone: module.transitivelyContainsExtensions)
1546+
.accept(this);
1547+
}
15361548

1537-
var visitor = _ImportedCssVisitor(this);
1538-
for (var child in children) {
1539-
child.accept(visitor);
1549+
var visitor = _ImportedCssVisitor(this);
1550+
for (var child in children) {
1551+
child.accept(visitor);
1552+
}
15401553
}
15411554

15421555
_activeModules.remove(url);

pkg/sass_api/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.0.0-beta.7
2+
3+
* No user-visible changes.
4+
15
## 1.0.0-beta.6
26

37
* Add the `SassApiColor` extension to the "Value" DartDoc category.

pkg/sass_api/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ name: sass_api
22
# Note: Every time we add a new Sass AST node, we need to bump the *major*
33
# version because it's a breaking change for anyone who's implementing the
44
# visitor interface(s).
5-
version: 1.0.0-beta.6
5+
version: 1.0.0-beta.7
66
description: Additional APIs for Dart Sass.
77
homepage: https://github.com/sass/dart-sass
88

99
environment:
1010
sdk: '>=2.12.0 <3.0.0'
1111

1212
dependencies:
13-
sass: 1.39.0
13+
sass: 1.39.1
1414

1515
dependency_overrides:
1616
sass: {path: ../..}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sass
2-
version: 1.39.0
2+
version: 1.39.1
33
description: A Sass implementation in Dart.
44
homepage: https://github.com/sass/dart-sass
55

0 commit comments

Comments
 (0)