Skip to content

Commit 204bc24

Browse files
committed
Cleanup
1 parent 917d164 commit 204bc24

File tree

2 files changed

+62
-57
lines changed

2 files changed

+62
-57
lines changed

lib/src/migrators/module.dart

Lines changed: 59 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,13 @@ class ModuleMigrator extends Migrator {
2424
final name = "module";
2525
final description = "Migrates stylesheets to the new module system.";
2626

27-
/// Global variables defined at any time during the migrator run.
28-
final _variables = normalizedMap<List<VariableDeclaration>>();
29-
30-
/// Global mixins defined at any time during the migrator run.
31-
final _mixins = normalizedMap<MixinRule>();
32-
33-
/// Global functions defined at any time during the migrator run.
34-
final _functions = normalizedMap<FunctionRule>();
35-
36-
/// Global variables declared with !default that could be configured.
37-
///final _configurableVariables = normalizedMap<VariableDeclaration>();
38-
3927
/// Runs the module migrator on [entrypoint] and its dependencies and returns
4028
/// a map of migrated contents.
4129
///
4230
/// If [migrateDependencies] is false, the migrator will still be run on
4331
/// dependencies, but they will be excluded from the resulting map.
4432
Map<Uri, String> migrateFile(Uri entrypoint) {
45-
var migrated = _ModuleMigrationVisitor(this).run(entrypoint);
33+
var migrated = _ModuleMigrationVisitor().run(entrypoint);
4634
if (!migrateDependencies) {
4735
migrated.removeWhere((url, contents) => url != entrypoint);
4836
}
@@ -51,7 +39,17 @@ class ModuleMigrator extends Migrator {
5139
}
5240

5341
class _ModuleMigrationVisitor extends MigrationVisitor {
54-
final ModuleMigrator migrator;
42+
/// Global variables defined at any time during the migrator run.
43+
///
44+
/// We store all declarations instead of just the most recent one for use in
45+
/// detecting configurable variables.
46+
final _globalVariables = normalizedMap<List<VariableDeclaration>>();
47+
48+
/// Global mixins defined at any time during the migrator run.
49+
final _globalMixins = normalizedMap<MixinRule>();
50+
51+
/// Global functions defined at any time during the migrator run.
52+
final _globalFunctions = normalizedMap<FunctionRule>();
5553

5654
/// Namespaces of modules used in this stylesheet.
5755
Map<Uri, String> _namespaces = {};
@@ -79,7 +77,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
7977
/// Note: We always set [migratedDependencies] to true since the module
8078
/// migrator needs to always run on dependencies. The `migrateFile` method of
8179
/// the module migrator will filter out the dependencies' migration results.
82-
_ModuleMigrationVisitor(this.migrator) : super(migrateDependencies: true);
80+
_ModuleMigrationVisitor() : super(migrateDependencies: true);
8381

8482
/// Returns the migrated contents of this stylesheet, based on [patches] and
8583
/// [_additionalUseRules], or null if the stylesheet does not change.
@@ -127,7 +125,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
127125
@override
128126
void visitFunctionExpression(FunctionExpression node) {
129127
visitInterpolation(node.name);
130-
patchNamespaceForFunction(node.name.asPlain, (name, namespace) {
128+
_patchNamespaceForFunction(node.name.asPlain, (name, namespace) {
131129
addPatch(Patch(node.name.span, "$namespace.$name"));
132130
});
133131
visitArgumentInvocation(node.arguments);
@@ -142,7 +140,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
142140
return;
143141
}
144142
var fnName = nameArgument as StringExpression;
145-
patchNamespaceForFunction(fnName.text.asPlain, (name, namespace) {
143+
_patchNamespaceForFunction(fnName.text.asPlain, (name, namespace) {
146144
var span = fnName.span;
147145
if (fnName.hasQuotes) {
148146
span = span.file.span(span.start.offset + 1, span.end.offset - 1);
@@ -162,13 +160,13 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
162160
/// when namespaced, and the namespace itself. The name will match the name
163161
/// provided to the outer function except for built-in functions whose name
164162
/// within a module differs from its original name.
165-
void patchNamespaceForFunction(
163+
void _patchNamespaceForFunction(
166164
String name, void patcher(String name, String namespace)) {
167165
if (name == null) return;
168166
if (_localScope?.isLocalFunction(name) ?? false) return;
169167

170-
var namespace = migrator._functions.containsKey(name)
171-
? namespaceForNode(migrator._functions[name])
168+
var namespace = _globalFunctions.containsKey(name)
169+
? _namespaceForNode(_globalFunctions[name])
172170
: null;
173171

174172
if (namespace == null) {
@@ -183,7 +181,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
183181
/// Declares the function within the current scope before visiting it.
184182
@override
185183
void visitFunctionRule(FunctionRule node) {
186-
declareFunction(node);
184+
_declareFunction(node);
187185
super.visitFunctionRule(node);
188186
}
189187

@@ -209,19 +207,33 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
209207
visitDependency(Uri.parse(import.url), _currentUrl);
210208
_namespaces[_lastUrl] = namespaceForPath(import.url);
211209

212-
var overrides = [];
213-
for (var name in migrator._variables.keys) {
214-
var declarations = migrator._variables[name];
210+
var configured = _findConfiguredVariables(node, import);
211+
var config = "";
212+
if (configured.isNotEmpty) {
213+
config = " with (\n " + configured.join(',\n ') + "\n)";
214+
}
215+
addPatch(Patch(node.span, '@use ${import.span.text}$config'));
216+
}
217+
218+
/// Finds all configured variables from the given import.
219+
///
220+
/// This returns a list of "$var: <expression>" strings that can be used to
221+
/// construct the configuration for a use rule.
222+
///
223+
/// If a variable was configured in a downstream stylesheet, this will instead
224+
/// add a forward rule to make it accessible.
225+
List<String> _findConfiguredVariables(ImportRule node, Import import) {
226+
var configured = <String>[];
227+
for (var name in _globalVariables.keys) {
228+
var declarations = _globalVariables[name];
215229
VariableDeclaration lastNonDefault = declarations[0];
216230
for (var i = 1; i < declarations.length; i++) {
217231
var declaration = declarations[i];
218232
if (!declaration.isGuarded) {
219233
lastNonDefault = declaration;
220234
} else if (declaration.span.sourceUrl == _lastUrl) {
221235
if (lastNonDefault.span.sourceUrl == _currentUrl) {
222-
// This configurable variable was set within the current stylesheet,
223-
// so add to overrides.
224-
overrides.add("\$$name: ${lastNonDefault.expression}");
236+
configured.add("\$$name: ${lastNonDefault.expression}");
225237
} else if (lastNonDefault.span.sourceUrl != _lastUrl) {
226238
// A downstream stylesheet configures this variable, so forward it.
227239
var semicolon = _currentUrl.path.endsWith('.sass') ? '' : ';';
@@ -235,20 +247,16 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
235247
}
236248
}
237249
}
238-
var config = "";
239-
if (overrides.isNotEmpty) {
240-
config = " with (\n " + overrides.join(',\n ') + "\n)";
241-
}
242-
addPatch(Patch(node.span, '@use ${import.span.text}$config'));
250+
return configured;
243251
}
244252

245253
/// Adds a namespace to any mixin include that requires it.
246254
@override
247255
void visitIncludeRule(IncludeRule node) {
248256
super.visitIncludeRule(node);
249257
if (_localScope?.isLocalMixin(node.name) ?? false) return;
250-
if (!migrator._mixins.containsKey(node.name)) return;
251-
var namespace = namespaceForNode(migrator._mixins[node.name]);
258+
if (!_globalMixins.containsKey(node.name)) return;
259+
var namespace = _namespaceForNode(_globalMixins[node.name]);
252260
if (namespace == null) return;
253261
var endName = node.arguments.span.start.offset;
254262
var startName = endName - node.name.length;
@@ -259,7 +267,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
259267
/// Declares the mixin within the current scope before visiting it.
260268
@override
261269
void visitMixinRule(MixinRule node) {
262-
declareMixin(node);
270+
_declareMixin(node);
263271
super.visitMixinRule(node);
264272
}
265273

@@ -276,63 +284,59 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
276284
if (_localScope?.isLocalVariable(node.name) ?? false) {
277285
return;
278286
}
279-
if (!migrator._variables.containsKey(node.name)) return;
280-
var lastRealDeclaration = migrator._variables[node.name]
287+
if (!_globalVariables.containsKey(node.name)) return;
288+
289+
/// Declarations where the expression is null are fake ones used to track
290+
/// configured variables within indirect dependencies.
291+
/// See [_findConfiguredVariables].
292+
var lastRealDeclaration = _globalVariables[node.name]
281293
.lastWhere((node) => node.expression != null);
282-
var namespace = namespaceForNode(lastRealDeclaration);
294+
var namespace = _namespaceForNode(lastRealDeclaration);
283295
if (namespace == null) return;
284296
addPatch(Patch(node.span, "\$$namespace.${node.name}"));
285297
}
286298

287299
/// Declares a variable within the current scope before visiting it.
288300
@override
289301
void visitVariableDeclaration(VariableDeclaration node) {
290-
declareVariable(node);
302+
_declareVariable(node);
291303
super.visitVariableDeclaration(node);
292304
}
293305

294306
/// Declares a variable within this stylesheet, in the current local scope if
295307
/// it exists, or as a global variable otherwise.
296-
void declareVariable(VariableDeclaration node) {
308+
void _declareVariable(VariableDeclaration node) {
297309
if (_localScope == null || node.isGlobal) {
298-
/*if (node.isGuarded) {
299-
migrator._configurableVariables[node.name] = node;
300-
301-
// Don't override if variable already exists.
302-
migrator._variables.putIfAbsent(node.name, () => node);
303-
} else {
304-
migrator._variables[node.name] = node;
305-
}*/
306-
migrator._variables.putIfAbsent(node.name, () => []);
307-
migrator._variables[node.name].add(node);
310+
_globalVariables.putIfAbsent(node.name, () => []);
311+
_globalVariables[node.name].add(node);
308312
} else {
309313
_localScope.variables.add(node.name);
310314
}
311315
}
312316

313317
/// Declares a mixin within this stylesheet, in the current local scope if
314318
/// it exists, or as a global mixin otherwise.
315-
void declareMixin(MixinRule node) {
319+
void _declareMixin(MixinRule node) {
316320
if (_localScope == null) {
317-
migrator._mixins[node.name] = node;
321+
_globalMixins[node.name] = node;
318322
} else {
319323
_localScope.mixins.add(node.name);
320324
}
321325
}
322326

323327
/// Declares a function within this stylesheet, in the current local scope if
324328
/// it exists, or as a global function otherwise.
325-
void declareFunction(FunctionRule node) {
329+
void _declareFunction(FunctionRule node) {
326330
if (_localScope == null) {
327-
migrator._functions[node.name] = node;
331+
_globalFunctions[node.name] = node;
328332
} else {
329333
_localScope.functions.add(node.name);
330334
}
331335
}
332336

333337
/// Finds the namespace for the stylesheet containing [node], adding a new use
334338
/// rule if necessary.
335-
String namespaceForNode(SassNode node) {
339+
String _namespaceForNode(SassNode node) {
336340
if (node.span.sourceUrl == _currentUrl) return null;
337341
if (!_namespaces.containsKey(node.span.sourceUrl)) {
338342
/// Add new use rule for indirect dependency

test/migrator_utils.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ _testHrx(File hrxFile, String migrator) async {
4949
migrated = await MigratorRunner().run(arguments);
5050
}, getCurrentDirectory: () => Directory(d.sandbox)),
5151
prints(files.expectedLog?.replaceAll("\$TEST_DIR", d.sandbox) ?? ""));
52-
var canonicalize = FilesystemImporter(d.sandbox).canonicalize;
52+
var importer = FilesystemImporter(d.sandbox);
5353
for (var file in files.input.keys) {
54-
expect(migrated[canonicalize(Uri.parse(file))], equals(files.output[file]),
54+
expect(migrated[importer.canonicalize(Uri.parse(file))],
55+
equals(files.output[file]),
5556
reason: 'Incorrect migration of $file.');
5657
}
5758
}

0 commit comments

Comments
 (0)