Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag to remove leading dashes and underscores #74

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 32 additions & 12 deletions lib/src/migrators/module.dart
Expand Up @@ -44,7 +44,13 @@ class ModuleMigrator extends Migrator {
},
defaultsTo: 'none',
help: 'Specifies which members from dependencies to forward from the '
'entrypoint.');
'entrypoint.')
..addFlag('dash-is-library-private',
help: "Treats members starting with `-` and `_` as private to the "
"overall library, but not to the individual module. This means "
"that leading dashes and underscores will be removed from member "
"names, but these members will not be forwarded from the "
"entrypoint, even if --forward=all.");

// Hide this until it's finished and the module system is launched.
final hidden = true;
Expand All @@ -65,7 +71,8 @@ class ModuleMigrator extends Migrator {
var migrated = _ModuleMigrationVisitor(
prefixToRemove:
(argResults['remove-prefix'] as String)?.replaceAll('_', '-'),
forward: forward)
forward: forward,
dashIsLibraryPrivate: argResults['dash-is-library-private'])
.run(entrypoint);
if (!migrateDependencies) {
migrated.removeWhere((url, contents) => url != entrypoint);
Expand Down Expand Up @@ -120,12 +127,16 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
/// The value of the --forward flag.
final ForwardType forward;

/// The value of the --dash-is-library-private flag.
final bool dashIsLibraryPrivate;

/// Constructs a new module migration visitor.
///
/// Note: We always set [migratedDependencies] to true since the module
/// migrator needs to always run on dependencies. The `migrateFile` method of
/// the module migrator will filter out the dependencies' migration results.
_ModuleMigrationVisitor({this.prefixToRemove, this.forward})
_ModuleMigrationVisitor(
{this.prefixToRemove, this.forward, this.dashIsLibraryPrivate})
: super(migrateDependencies: true);

/// Returns a semicolon unless the current stylesheet uses the indented
Expand Down Expand Up @@ -176,7 +187,11 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
var hidden = <Uri, Set<String>>{};
categorizeMember(Uri url, String originalName, String newName) {
if (url == _currentUrl) return;
if (_shouldForward(originalName)) {
if (!dashIsLibraryPrivate && originalName.startsWith('-')) {
// This remains module-private, so we don't need to manually hide it.
return;
} else if (_shouldForward(originalName) &&
!originalName.startsWith('-')) {
shown[url] ??= {};
shown[url].add(newName);
} else {
Expand Down Expand Up @@ -603,8 +618,8 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
if (_scope.isGlobal || node.isGlobal) {
name = _unprefix(node.name);
if (name != node.name) {
addPatch(
patchDelete(node.span, start: 1, end: prefixToRemove.length + 1));
var removedLength = node.name.length - name.length;
addPatch(patchDelete(node.span, start: 1, end: removedLength + 1));
}
var existingNode = _scope.global.variables[name];
var originalUrl = existingNode?.span?.sourceUrl;
Expand Down Expand Up @@ -659,14 +674,19 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
_scope.functions[name] = node;
}

/// Returns [name] with [prefixToRemove] removed.
/// Returns [name] with some prefix removed.
///
/// The removed prefix can be [prefixToRemove] (if set) or a dash or
/// underscore if [dashIsLibraryPrivate] is true. If [name] starts with a
/// dash or underscore followed by [prefixToRemove], both will be removed.
String _unprefix(String name) {
if (prefixToRemove == null || prefixToRemove.length > name.length) {
return name;
if (dashIsLibraryPrivate && name.startsWith('-')) name = name.substring(1);
if (prefixToRemove != null &&
prefixToRemove.length < name.length &&
prefixToRemove == name.substring(0, prefixToRemove.length)) {
name = name.substring(prefixToRemove.length);
}
var startOfName = name.substring(0, prefixToRemove.length);
if (prefixToRemove != startOfName) return name;
return name.substring(prefixToRemove.length);
return name;
}

/// Finds the namespace for the stylesheet containing [node], adding a new use
Expand Down
25 changes: 25 additions & 0 deletions test/migrators/module/forward_pseudoprivate.hrx
@@ -0,0 +1,25 @@
<==> arguments
--migrate-deps --forward=all --dash-is-library-private

<==> input/entrypoint.scss
@import "dependency";

a {
color: $_pseudoprivate;
}

<==> input/_dependency.scss
$public: red;
$-pseudoprivate: blue;

<==> output/entrypoint.scss
@forward "dependency" hide $pseudoprivate;
@use "dependency";

a {
color: $dependency.pseudoprivate;
}

<==> output/_dependency.scss
$public: red;
$pseudoprivate: blue;
24 changes: 24 additions & 0 deletions test/migrators/module/pseudoprivate.hrx
@@ -0,0 +1,24 @@
<==> arguments
--migrate-deps --dash-is-library-private

<==> input/entrypoint.scss
@import "library";
a {
color: $-dash;
background: $_underscore;
}

<==> input/_library.scss
$-dash: red;
$-underscore: blue;

<==> output/entrypoint.scss
@use "library";
a {
color: $library.dash;
background: $library.underscore;
}

<==> output/_library.scss
$dash: red;
$underscore: blue;
27 changes: 27 additions & 0 deletions test/migrators/module/unprefix_pseudoprivate.hrx
@@ -0,0 +1,27 @@
<==> arguments
--migrate-deps --forward=all --dash-is-library-private --remove-prefix=lib-

<==> input/entrypoint.scss
@import "dependency";

a {
color: $lib-public;
background: $_lib-pseudoprivate;
}

<==> input/_dependency.scss
$lib-public: red;
$_lib-pseudoprivate: blue;

<==> output/entrypoint.scss
@forward "dependency" hide $pseudoprivate;
@use "dependency";

a {
color: $dependency.public;
background: $dependency.pseudoprivate;
}

<==> output/_dependency.scss
$public: red;
$pseudoprivate: blue;