Skip to content

Commit e9e44d7

Browse files
authored
Emit comments in source order where possible (#1989)
See sass/sass#2848 Closes #1939
1 parent 2bece76 commit e9e44d7

File tree

12 files changed

+222
-105
lines changed

12 files changed

+222
-105
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.64.0
2+
3+
* Comments that appear before or between `@use` and `@forward` rules are now
4+
emitted in source order as much as possible, instead of always being emitted
5+
after the CSS of all module dependencies.
6+
17
## 1.63.6
28

39
### JavaScript API

lib/src/ast/css/modifiable/node.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,13 @@ abstract class ModifiableCssParentNode extends ModifiableCssNode
8181
child._indexInParent = _children.length;
8282
_children.add(child);
8383
}
84+
85+
/// Destructively removes all elements from [children].
86+
void clearChildren() {
87+
for (var child in _children) {
88+
child._parent = null;
89+
child._indexInParent = null;
90+
}
91+
_children.clear();
92+
}
8493
}

lib/src/async_environment.dart

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -802,11 +802,14 @@ class AsyncEnvironment {
802802
}
803803

804804
/// Returns a module that represents the top-level members defined in [this],
805-
/// that contains [css] as its CSS tree, which can be extended using
806-
/// [extensionStore].
807-
Module toModule(CssStylesheet css, ExtensionStore extensionStore) {
805+
/// that contains [css] and [preModuleComments] as its CSS, which can be
806+
/// extended using [extensionStore].
807+
Module toModule(
808+
CssStylesheet css,
809+
Map<Module, List<CssComment>> preModuleComments,
810+
ExtensionStore extensionStore) {
808811
assert(atRoot);
809-
return _EnvironmentModule(this, css, extensionStore,
812+
return _EnvironmentModule(this, css, preModuleComments, extensionStore,
810813
forwarded: _forwardedModules.andThen((modules) => MapKeySet(modules)));
811814
}
812815

@@ -821,6 +824,7 @@ class AsyncEnvironment {
821824
this,
822825
CssStylesheet(const [],
823826
SourceFile.decoded(const [], url: "<dummy module>").span(0)),
827+
const {},
824828
ExtensionStore.empty,
825829
forwarded: _forwardedModules.andThen((modules) => MapKeySet(modules)));
826830
}
@@ -902,6 +906,7 @@ class _EnvironmentModule implements Module {
902906
final Map<String, AsyncCallable> mixins;
903907
final ExtensionStore extensionStore;
904908
final CssStylesheet css;
909+
final Map<Module, List<CssComment>> preModuleComments;
905910
final bool transitivelyContainsCss;
906911
final bool transitivelyContainsExtensions;
907912

@@ -916,13 +921,20 @@ class _EnvironmentModule implements Module {
916921
/// defined at all.
917922
final Map<String, Module> _modulesByVariable;
918923

919-
factory _EnvironmentModule(AsyncEnvironment environment, CssStylesheet css,
924+
factory _EnvironmentModule(
925+
AsyncEnvironment environment,
926+
CssStylesheet css,
927+
Map<Module, List<CssComment>> preModuleComments,
920928
ExtensionStore extensionStore,
921929
{Set<Module>? forwarded}) {
922930
forwarded ??= const {};
923931
return _EnvironmentModule._(
924932
environment,
925933
css,
934+
Map.unmodifiable({
935+
for (var entry in preModuleComments.entries)
936+
entry.key: List<CssComment>.unmodifiable(entry.value)
937+
}),
926938
extensionStore,
927939
_makeModulesByVariable(forwarded),
928940
_memberMap(environment._variables.first,
@@ -934,6 +946,7 @@ class _EnvironmentModule implements Module {
934946
_memberMap(environment._mixins.first,
935947
forwarded.map((module) => module.mixins)),
936948
transitivelyContainsCss: css.children.isNotEmpty ||
949+
preModuleComments.isNotEmpty ||
937950
environment._allModules
938951
.any((module) => module.transitivelyContainsCss),
939952
transitivelyContainsExtensions: !extensionStore.isEmpty ||
@@ -981,6 +994,7 @@ class _EnvironmentModule implements Module {
981994
_EnvironmentModule._(
982995
this._environment,
983996
this.css,
997+
this.preModuleComments,
984998
this.extensionStore,
985999
this._modulesByVariable,
9861000
this.variables,
@@ -1020,6 +1034,7 @@ class _EnvironmentModule implements Module {
10201034
return _EnvironmentModule._(
10211035
_environment,
10221036
newCssAndExtensionStore.item1,
1037+
preModuleComments,
10231038
newCssAndExtensionStore.item2,
10241039
_modulesByVariable,
10251040
variables,

lib/src/environment.dart

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_environment.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: 38c688423116df1e489aa6eafc16de1bf9bc2bf5
8+
// Checksum: 487c34d7387b6f368ed60ff2db6a748483aba2a1
99
//
1010
// ignore_for_file: unused_import
1111

@@ -808,11 +808,14 @@ class Environment {
808808
}
809809

810810
/// Returns a module that represents the top-level members defined in [this],
811-
/// that contains [css] as its CSS tree, which can be extended using
812-
/// [extensionStore].
813-
Module<Callable> toModule(CssStylesheet css, ExtensionStore extensionStore) {
811+
/// that contains [css] and [preModuleComments] as its CSS, which can be
812+
/// extended using [extensionStore].
813+
Module<Callable> toModule(
814+
CssStylesheet css,
815+
Map<Module<Callable>, List<CssComment>> preModuleComments,
816+
ExtensionStore extensionStore) {
814817
assert(atRoot);
815-
return _EnvironmentModule(this, css, extensionStore,
818+
return _EnvironmentModule(this, css, preModuleComments, extensionStore,
816819
forwarded: _forwardedModules.andThen((modules) => MapKeySet(modules)));
817820
}
818821

@@ -827,6 +830,7 @@ class Environment {
827830
this,
828831
CssStylesheet(const [],
829832
SourceFile.decoded(const [], url: "<dummy module>").span(0)),
833+
const {},
830834
ExtensionStore.empty,
831835
forwarded: _forwardedModules.andThen((modules) => MapKeySet(modules)));
832836
}
@@ -909,6 +913,7 @@ class _EnvironmentModule implements Module<Callable> {
909913
final Map<String, Callable> mixins;
910914
final ExtensionStore extensionStore;
911915
final CssStylesheet css;
916+
final Map<Module<Callable>, List<CssComment>> preModuleComments;
912917
final bool transitivelyContainsCss;
913918
final bool transitivelyContainsExtensions;
914919

@@ -924,12 +929,19 @@ class _EnvironmentModule implements Module<Callable> {
924929
final Map<String, Module<Callable>> _modulesByVariable;
925930

926931
factory _EnvironmentModule(
927-
Environment environment, CssStylesheet css, ExtensionStore extensionStore,
932+
Environment environment,
933+
CssStylesheet css,
934+
Map<Module<Callable>, List<CssComment>> preModuleComments,
935+
ExtensionStore extensionStore,
928936
{Set<Module<Callable>>? forwarded}) {
929937
forwarded ??= const {};
930938
return _EnvironmentModule._(
931939
environment,
932940
css,
941+
Map.unmodifiable({
942+
for (var entry in preModuleComments.entries)
943+
entry.key: List<CssComment>.unmodifiable(entry.value)
944+
}),
933945
extensionStore,
934946
_makeModulesByVariable(forwarded),
935947
_memberMap(environment._variables.first,
@@ -941,6 +953,7 @@ class _EnvironmentModule implements Module<Callable> {
941953
_memberMap(environment._mixins.first,
942954
forwarded.map((module) => module.mixins)),
943955
transitivelyContainsCss: css.children.isNotEmpty ||
956+
preModuleComments.isNotEmpty ||
944957
environment._allModules
945958
.any((module) => module.transitivelyContainsCss),
946959
transitivelyContainsExtensions: !extensionStore.isEmpty ||
@@ -989,6 +1002,7 @@ class _EnvironmentModule implements Module<Callable> {
9891002
_EnvironmentModule._(
9901003
this._environment,
9911004
this.css,
1005+
this.preModuleComments,
9921006
this.extensionStore,
9931007
this._modulesByVariable,
9941008
this.variables,
@@ -1028,6 +1042,7 @@ class _EnvironmentModule implements Module<Callable> {
10281042
return _EnvironmentModule._(
10291043
_environment,
10301044
newCssAndExtensionStore.item1,
1045+
preModuleComments,
10311046
newCssAndExtensionStore.item2,
10321047
_modulesByVariable,
10331048
variables,

lib/src/module.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ abstract class Module<T extends AsyncCallable> {
5353
/// The module's CSS tree.
5454
CssStylesheet get css;
5555

56+
/// A map from modules in [upstream] to loud comments written in this module
57+
/// that should be emitted before the given module.
58+
Map<Module<T>, List<CssComment>> get preModuleComments;
59+
5660
/// Whether this module *or* any modules in [upstream] contain any CSS.
5761
bool get transitivelyContainsCss;
5862

lib/src/module/built_in.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class BuiltInModule<T extends AsyncCallable> implements Module<T> {
2323
Map<String, AstNode> get variableNodes => const {};
2424
ExtensionStore get extensionStore => ExtensionStore.empty;
2525
CssStylesheet get css => CssStylesheet.empty(url: url);
26+
Map<Module<T>, List<CssComment>> get preModuleComments => const {};
2627
bool get transitivelyContainsCss => false;
2728
bool get transitivelyContainsExtensions => false;
2829

lib/src/module/forwarded_view.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class ForwardedModuleView<T extends AsyncCallable> implements Module<T> {
2525
List<Module<T>> get upstream => _inner.upstream;
2626
ExtensionStore get extensionStore => _inner.extensionStore;
2727
CssStylesheet get css => _inner.css;
28+
Map<Module<T>, List<CssComment>> get preModuleComments =>
29+
_inner.preModuleComments;
2830
bool get transitivelyContainsCss => _inner.transitivelyContainsCss;
2931
bool get transitivelyContainsExtensions =>
3032
_inner.transitivelyContainsExtensions;

lib/src/module/shadowed_view.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class ShadowedModuleView<T extends AsyncCallable> implements Module<T> {
2222
List<Module<T>> get upstream => _inner.upstream;
2323
ExtensionStore get extensionStore => _inner.extensionStore;
2424
CssStylesheet get css => _inner.css;
25+
Map<Module<T>, List<CssComment>> get preModuleComments =>
26+
_inner.preModuleComments;
2527
bool get transitivelyContainsCss => _inner.transitivelyContainsCss;
2628
bool get transitivelyContainsExtensions =>
2729
_inner.transitivelyContainsExtensions;

0 commit comments

Comments
 (0)