diff --git a/CHANGELOG.md b/CHANGELOG.md index 88ad916..1f94604 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.1 + +- Optimizations and Refactoring of String operations + ## 1.1.0 - Added an option to disable dart formatter diff --git a/bin/better_imports.dart b/bin/better_imports.dart index dcc4bc3..30711bb 100644 --- a/bin/better_imports.dart +++ b/bin/better_imports.dart @@ -12,8 +12,8 @@ import "package:better_imports/src/arg_parser.dart"; import "package:better_imports/src/cfg.dart"; import "package:better_imports/src/constants.dart"; import "package:better_imports/src/file_extension.dart"; -import "package:better_imports/src/file_path_collector.dart"; -import "package:better_imports/src/import_sorter.dart"; +import "package:better_imports/src/file_paths_collector.dart"; +import "package:better_imports/src/files_sorter.dart"; import "package:better_imports/src/log.dart"; import "package:better_imports/src/sorted_result.dart"; diff --git a/bin/better_imports.exe b/bin/better_imports.exe deleted file mode 100644 index 7cdec06..0000000 Binary files a/bin/better_imports.exe and /dev/null differ diff --git a/lib/src/cfg.dart b/lib/src/cfg.dart index 88f315d..9f5020b 100644 --- a/lib/src/cfg.dart +++ b/lib/src/cfg.dart @@ -95,7 +95,7 @@ class Cfg { _setTrace(); _setRelative(); _setDryRun(); - _setNoDartFmt(); + _setDartFmt(); _setFolders(); @@ -270,7 +270,7 @@ class Cfg { } } - void _setNoDartFmt() { + void _setDartFmt() { log.fine("┠─ Setting dart fmt.."); if (_biYamlSection != null && _biYamlSection![Constants.dartFmt] != null) { diff --git a/lib/src/constants.dart b/lib/src/constants.dart index 64c3b85..11c04f3 100644 --- a/lib/src/constants.dart +++ b/lib/src/constants.dart @@ -51,11 +51,11 @@ class Constants { static const projectNameOption = "project-name"; - static const dartImportsComment = "// Dart Imports"; - static const flutterImportsComment = "// Flutter Imports"; - static const packageImportsComment = "// Package Imports"; - static const projectImportsComment = "// Project Imports"; - static const relativeProjectImportsComment = "// Relative Project Imports"; + static const dartComment = "// Dart Imports"; + static const flutterComment = "// Flutter Imports"; + static const packageComment = "// Package Imports"; + static const projectComment = "// Project Imports"; + static const relativeComment = "// Relative Project Imports"; static final title = """ _ _ _ diff --git a/lib/src/import_type.dart b/lib/src/directive_type.dart similarity index 77% rename from lib/src/import_type.dart rename to lib/src/directive_type.dart index 0082533..b76e623 100644 --- a/lib/src/import_type.dart +++ b/lib/src/directive_type.dart @@ -1,4 +1,4 @@ -enum ImportType { +enum DirectiveType { library, dart, flutter, diff --git a/lib/src/directives_sorter.dart b/lib/src/directives_sorter.dart new file mode 100644 index 0000000..24a6039 --- /dev/null +++ b/lib/src/directives_sorter.dart @@ -0,0 +1,130 @@ +// Project Imports +import 'package:better_imports/src/cfg.dart'; +import 'package:better_imports/src/constants.dart'; +import 'package:better_imports/src/directive_type.dart'; +import 'package:better_imports/src/log.dart'; + +String sort( + String path, + Map>> directivesWithComments, + Cfg cfg, +) { + final buffer = StringBuffer(); + var projectDirectives = directivesWithComments[DirectiveType.project]!; + var convertedProjectDirectives = + _convertProjectImports(path, projectDirectives, cfg); + + _add(buffer, directivesWithComments[DirectiveType.library]!, "", cfg); + _add(buffer, directivesWithComments[DirectiveType.dart]!, + Constants.dartComment, cfg); + _add(buffer, directivesWithComments[DirectiveType.flutter]!, + Constants.flutterComment, cfg); + _add(buffer, directivesWithComments[DirectiveType.package]!, + Constants.packageComment, cfg); + _add(buffer, convertedProjectDirectives, Constants.projectComment, cfg); + _add(buffer, directivesWithComments[DirectiveType.relative]!, + Constants.relativeComment, cfg); + _add(buffer, directivesWithComments[DirectiveType.part]!, "", cfg); + + return buffer.toString(); +} + +Map> _convertProjectImports( + String path, + Map> projectDirectives, + Cfg cfg, +) { + log.fine("┠── Processing project imports.."); + + var newProjectImports = >{}; + + for (var directiveValue in projectDirectives.keys) { + var convertedDirectiveValue = ""; + + if (cfg.relative) { + convertedDirectiveValue = + _convertToRelativeProjectImport(path, directiveValue, cfg); + } else { + convertedDirectiveValue = + _convertToPackageProjectImport(path, directiveValue, cfg); + } + + newProjectImports.putIfAbsent( + convertedDirectiveValue, () => projectDirectives[directiveValue]!); + } + + return newProjectImports; +} + +String _convertToRelativeProjectImport( + String path, + String importLine, + Cfg cfg, +) { + log.fine("┠─── Converting to relative project import.."); + + if (importLine.contains("..")) { + return importLine; + } + + if (importLine.contains("'package:${cfg.projectName}")) { + if (!path.contains("lib")) { + return importLine.replaceFirst("package:${cfg.projectName}", "../lib"); + } else { + return importLine.replaceFirst("package:${cfg.projectName}", ".."); + } + } + + return importLine; +} + +String _convertToPackageProjectImport( + String path, + String directiveValue, + Cfg cfg, +) { + log.fine("┠─── Converting to project import.."); + + if (directiveValue.startsWith("import 'package:${cfg.projectName}")) { + return directiveValue; + } + + if (!directiveValue.contains("lib")) { + directiveValue = directiveValue.replaceFirst("lib/", ""); + } + + if (directiveValue.contains("..")) { + return directiveValue.replaceFirst("..", "package:${cfg.projectName}"); + } else { + return directiveValue.replaceFirst( + "import '", "import 'package:${cfg.projectName}/"); + } +} + +void _add( + StringBuffer buffer, + Map> directives, + String directiveTypeComment, + Cfg cfg, +) { + try { + if (directives.isNotEmpty) { + buffer.writeln(); + + if (cfg.comments && directiveTypeComment.isNotEmpty) { + buffer.writeln(directiveTypeComment); + } + + for (var directive in directives.keys) { + var comments = directives[directive]!; + if (comments.isNotEmpty) { + buffer.writeln(comments.join("\n")); + } + + buffer.writeln(directive); + } + } + } catch (e, s) { + log.severe("Error adding directives and comments: $e\n$s"); + } +} diff --git a/lib/src/file_path_collector_result.dart b/lib/src/file_path_collector_result.dart deleted file mode 100644 index 9be0f05..0000000 --- a/lib/src/file_path_collector_result.dart +++ /dev/null @@ -1,7 +0,0 @@ -class FilePathCollectorResult { - final List allPaths; - final List filteredPaths; - - FilePathCollectorResult( - {required this.allPaths, required this.filteredPaths}); -} diff --git a/lib/src/file_paths.dart b/lib/src/file_paths.dart new file mode 100644 index 0000000..cd55ed5 --- /dev/null +++ b/lib/src/file_paths.dart @@ -0,0 +1,6 @@ +class FilePaths { + final List allPaths; + final List filteredPaths; + + FilePaths({required this.allPaths, required this.filteredPaths}); +} diff --git a/lib/src/file_path_collector.dart b/lib/src/file_paths_collector.dart similarity index 94% rename from lib/src/file_path_collector.dart rename to lib/src/file_paths_collector.dart index ec34b58..a055029 100644 --- a/lib/src/file_path_collector.dart +++ b/lib/src/file_paths_collector.dart @@ -3,7 +3,7 @@ import 'dart:io'; // Project Imports import 'package:better_imports/src/cfg.dart'; -import 'package:better_imports/src/file_path_collector_result.dart'; +import 'package:better_imports/src/file_paths.dart'; import 'package:better_imports/src/log.dart'; class FilePathsCollector { @@ -13,14 +13,14 @@ class FilePathsCollector { FilePathsCollector({required this.cfg}); - FilePathCollectorResult collect() { + FilePaths collect() { _collectInFolders(); _filteredFilePaths.addAll(List.from(_allFilePaths)); _filterFilePaths(); - return FilePathCollectorResult( + return FilePaths( allPaths: _allFilePaths, filteredPaths: _filteredFilePaths, ); diff --git a/lib/src/files_sorter.dart b/lib/src/files_sorter.dart new file mode 100644 index 0000000..da64c71 --- /dev/null +++ b/lib/src/files_sorter.dart @@ -0,0 +1,310 @@ +// Dart Imports +import 'dart:io'; + +// Package Imports +import 'package:analyzer/dart/analysis/utilities.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/ast/token.dart'; +import 'package:dart_style/dart_style.dart'; + +// Project Imports +import 'package:better_imports/src/cfg.dart'; +import 'package:better_imports/src/constants.dart'; +import 'package:better_imports/src/directive_type.dart'; +import 'package:better_imports/src/directives_sorter.dart' as sorter; +import 'package:better_imports/src/file_paths.dart'; +import 'package:better_imports/src/log.dart'; +import 'package:better_imports/src/sorted_result.dart'; + +List sort(FilePaths collectorResult, Cfg cfg) { + var results = []; + + for (var path in collectorResult.filteredPaths) { + var sortedResult = _sortFile(path, collectorResult, cfg); + + if (sortedResult.changed && !cfg.dryRun) { + sortedResult.file.writeAsStringSync(sortedResult.sortedContent); + } + + results.add(sortedResult); + } + + return results; +} + +SortedResult _sortFile(String path, FilePaths collectorResult, Cfg cfg) { + log.fine("┠─ Sorting file: $path"); + + var fileContent = File(path).readAsStringSync(); + var compilationUnit = parseString(content: fileContent).unit; + + if (compilationUnit.directives.isEmpty) { + return SortedResult( + file: File(path), + sortedContent: fileContent, + changed: false, + ); + } + + var lastDirective = compilationUnit.directives.last.toString(); + var directiveEndIndex = + fileContent.indexOf(lastDirective) + lastDirective.length; + + var directivesContent = fileContent.substring(0, directiveEndIndex); + var directivesCompilationUnit = parseString(content: directivesContent).unit; + + var remainingContent = fileContent.substring(directiveEndIndex); + + var directivesWithComments = >>{}; + + _initDirectivesToComments(directivesWithComments); + _fillDirectivesToComments( + directivesCompilationUnit, directivesWithComments, collectorResult, cfg); + + var sortedDirectives = sorter.sort(path, directivesWithComments, cfg); + + var formatter = DartFormatter(); + + var sortedContent = formatter.format(sortedDirectives) + + remainingContent.substring(1, remainingContent.length); + + if (_areImportsEmpty(directivesWithComments)) { + return SortedResult( + file: File(path), + sortedContent: fileContent, + changed: false, + ); + } + + if (cfg.dartFmt) { + sortedContent = formatter.format(sortedContent); + } + + return SortedResult( + file: File(path), + sortedContent: sortedContent, + changed: fileContent.compareTo(sortedContent) != 0, + ); +} + +void _initDirectivesToComments( + Map>> directivesToComments) { + log.fine("┠─ Initializing directives types to directives and comments.."); + + directivesToComments.putIfAbsent(DirectiveType.library, () => {}); + directivesToComments.putIfAbsent(DirectiveType.dart, () => {}); + directivesToComments.putIfAbsent(DirectiveType.flutter, () => {}); + directivesToComments.putIfAbsent(DirectiveType.package, () => {}); + directivesToComments.putIfAbsent(DirectiveType.project, () => {}); + directivesToComments.putIfAbsent(DirectiveType.relative, () => {}); + directivesToComments.putIfAbsent(DirectiveType.part, () => {}); +} + +void _fillDirectivesToComments( + CompilationUnit unit, + Map>> directivesToComments, + FilePaths collectorResult, + Cfg cfg, +) { + log.fine("┠─ Filling directive types to directives and comments.."); + + for (var directive in unit.directives) { + var directiveValue = directive.toString(); + var directiveType = _getDirectiveType(directiveValue, collectorResult, cfg); + var directiveComments = directivesToComments[directiveType]; + + directiveComments!.putIfAbsent(directiveValue, () => []); + + Token? beginToken = directive.beginToken; + + if (directive is ImportDirective) { + if (beginToken.lexeme.startsWith("///")) { + _extractDocCommentsFromImportDirective(directive, directiveComments); + } else { + _extractPrecedingCommentsFromImportDirective( + directive, directiveComments); + } + } else if (directive is LibraryDirective) { + if (beginToken.lexeme.startsWith("///")) { + _extractDocCommentsFromLibraryDirective(directive, directiveComments); + } else { + _extractPrecedingCommentsFromLibraryDirective( + directive, directiveComments); + } + } else if (directive is PartDirective) { + if (beginToken.lexeme.startsWith("///")) { + _extractDocCommentsFromPartDirective(directive, directiveComments); + } else { + _extractPrecedingCommentsFromPartDirective( + directive, directiveComments); + } + } + } +} + +DirectiveType _getDirectiveType( + String directiveValue, + FilePaths collectorResult, + Cfg cfg, +) { + if (directiveValue.contains("library")) { + return DirectiveType.library; + } else if (directiveValue.contains("part")) { + return DirectiveType.part; + } else if (directiveValue.contains('dart:')) { + return DirectiveType.dart; + } else if (directiveValue.contains('package:flutter')) { + return DirectiveType.flutter; + } else if (directiveValue.contains('package:${cfg.projectName}')) { + return DirectiveType.project; + } else if (!directiveValue.contains('package:')) { + var fileName = _extractFileName(directiveValue); + var filePath = + collectorResult.allPaths.firstWhere((path) => path.contains(fileName)); + + if (filePath.contains("lib/")) { + return DirectiveType.project; + } else { + return DirectiveType.relative; + } + } else { + return DirectiveType.package; + } +} + +String _extractFileName(String import) { + Uri uri = Uri.parse(_extractPathFromImport(import)); + return uri.pathSegments.last; +} + +String _extractPathFromImport(String importStatement) { + var matches = RegExp(r"'([^']*)'").allMatches(importStatement); + return matches.first.group(1) ?? ''; +} + +void _extractDocCommentsFromLibraryDirective( + LibraryDirective directive, + Map> inputTypeEntry, +) { + log.fine("┠── Extracting doc comments.."); + + _extractDocComments( + directive.toString(), directive.beginToken, inputTypeEntry); +} + +void _extractDocCommentsFromImportDirective( + ImportDirective directive, + Map> inputTypeEntry, +) { + log.fine("┠── Extracting doc comments.."); + + _extractDocComments( + directive.toString(), directive.beginToken, inputTypeEntry); +} + +void _extractDocCommentsFromPartDirective( + PartDirective directive, + Map> inputTypeEntry, +) { + log.fine("┠── Extracting doc comments.."); + + _extractDocComments( + directive.toString(), directive.beginToken, inputTypeEntry); +} + +void _extractDocComments( + String directiveValue, + Token? beginToken, + Map> directiveToComments, +) { + while (beginToken != null) { + if (!_isImportComment(beginToken.lexeme)) { + directiveToComments[directiveValue]!.add(beginToken.lexeme); + } + + beginToken = beginToken.next; + } +} + +void _extractPrecedingCommentsFromImportDirective( + ImportDirective directive, + Map> directiveToComments, +) { + log.fine("┠── Extracting preceding comments.."); + + dynamic precedingComment = directive.beginToken.precedingComments; + + if (precedingComment == null) { + return; + } + + _extractPrecedingComments( + precedingComment, directiveToComments, directive.toString()); +} + +void _extractPrecedingCommentsFromLibraryDirective( + LibraryDirective directive, + Map> directiveToComments, +) { + log.fine("┠── Extracting preceding comments.."); + + dynamic precedingComment = directive.beginToken.precedingComments; + + if (precedingComment == null) { + return; + } + + _extractPrecedingComments( + precedingComment, directiveToComments, directive.toString()); +} + +void _extractPrecedingCommentsFromPartDirective( + PartDirective directive, + Map> directiveToComments, +) { + log.fine("┠── Extracting preceding comments.."); + + Token? precedingComment = directive.beginToken.precedingComments; + + if (precedingComment == null) { + return; + } + + _extractPrecedingComments( + precedingComment, directiveToComments, directive.toString()); +} + +void _extractPrecedingComments( + Token? precedingComment, + Map> directiveToComments, + String directiveValue, +) { + while (precedingComment != null) { + if (!_isImportComment(precedingComment.toString())) { + directiveToComments[directiveValue]!.add(precedingComment.toString()); + } + + precedingComment = precedingComment.next; + } +} + +bool _isImportComment(String comment) { + return comment == Constants.dartComment || + comment == Constants.flutterComment || + comment == Constants.packageComment || + comment == Constants.projectComment || + comment == Constants.relativeComment; +} + +bool _areImportsEmpty( + Map>> directives) { + for (var importType in directives.keys) { + var entry = directives[importType]; + + if (entry!.isNotEmpty) { + return false; + } + } + + return true; +} diff --git a/lib/src/import_sorter.dart b/lib/src/import_sorter.dart deleted file mode 100644 index 16b68d1..0000000 --- a/lib/src/import_sorter.dart +++ /dev/null @@ -1,456 +0,0 @@ -// Dart Imports -import 'dart:io'; - -// Package Imports -import 'package:analyzer/dart/analysis/utilities.dart'; -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/dart/ast/token.dart'; -import 'package:dart_style/dart_style.dart'; - -// Project Imports -import 'package:better_imports/src/cfg.dart'; -import 'package:better_imports/src/constants.dart'; -import 'package:better_imports/src/file_path_collector_result.dart'; -import 'package:better_imports/src/import_type.dart'; -import 'package:better_imports/src/log.dart'; -import 'package:better_imports/src/sorted_result.dart'; - -List sort(FilePathCollectorResult collectorResult, Cfg cfg) { - var results = []; - - for (var path in collectorResult.filteredPaths) { - var sortedResult = _sortFile(path, collectorResult, cfg); - - if (sortedResult.changed && !cfg.dryRun) { - sortedResult.file.writeAsStringSync(sortedResult.sortedContent); - } - - results.add(sortedResult); - } - - return results; -} - -SortedResult _sortFile( - String path, - FilePathCollectorResult collectorResult, - Cfg cfg, -) { - log.fine("┠─ Sorting file: $path"); - - var raw = File(path).readAsStringSync(); - var rawUnit = parseString(content: raw).unit; - - if (rawUnit.directives.isEmpty) { - return SortedResult( - file: File(path), - sortedContent: raw, - changed: false, - ); - } - - var lastDirective = rawUnit.directives.last.toString(); - var directiveEndIndex = raw.indexOf(lastDirective) + lastDirective.length; - - var directives = raw.substring(0, directiveEndIndex); - var rawWithoutDirectives = raw.substring(directiveEndIndex); - - var directivesUnit = parseString(content: directives).unit; - - var directivesToComments = >>{}; - - _initDirectivesToComments(directivesToComments); - _fillDirectivesToComments( - directivesUnit, directivesToComments, collectorResult, cfg); - - var sortedDirectives = _sortDirectives(path, directivesToComments, cfg); - - var formatter = DartFormatter(); - - var sortedContent = formatter.format(sortedDirectives) + - rawWithoutDirectives.substring(1, rawWithoutDirectives.length); - - if (_areImportsEmpty(directivesToComments)) { - return SortedResult( - file: File(path), - sortedContent: raw, - changed: false, - ); - } - - if (cfg.dartFmt) { - sortedContent = formatter.format(sortedContent); - } - - return SortedResult( - file: File(path), - sortedContent: sortedContent, - changed: raw.compareTo(sortedContent) != 0, - ); -} - -void _initDirectivesToComments( - Map>> directivesToComments) { - log.fine("┠─ Initializing directives types to directives and comments.."); - - directivesToComments.putIfAbsent(ImportType.library, () => {}); - directivesToComments.putIfAbsent(ImportType.dart, () => {}); - directivesToComments.putIfAbsent(ImportType.flutter, () => {}); - directivesToComments.putIfAbsent(ImportType.package, () => {}); - directivesToComments.putIfAbsent(ImportType.project, () => {}); - directivesToComments.putIfAbsent(ImportType.relative, () => {}); - directivesToComments.putIfAbsent(ImportType.part, () => {}); -} - -void _fillDirectivesToComments( - CompilationUnit unit, - Map>> directivesToComments, - FilePathCollectorResult collectorResult, - Cfg cfg, -) { - log.fine("┠─ Filling directive types to directives and comments.."); - - for (var directive in unit.directives) { - var directiveValue = directive.toString(); - var directiveType = _getDirectiveType(directiveValue, collectorResult, cfg); - var directiveComments = directivesToComments[directiveType]; - - directiveComments!.putIfAbsent(directiveValue, () => []); - - Token? beginToken = directive.beginToken; - - if (directive is ImportDirective) { - if (beginToken.lexeme.startsWith("///")) { - _extractDocCommentsFromImportDirective(directive, directiveComments); - } else { - _extractPrecedingCommentsFromImportDirective( - directive, directiveComments); - } - } else if (directive is LibraryDirective) { - if (beginToken.lexeme.startsWith("///")) { - _extractDocCommentsFromLibraryDirective(directive, directiveComments); - } else { - _extractPrecedingCommentsFromLibraryDirective( - directive, directiveComments); - } - } else if (directive is PartDirective) { - if (beginToken.lexeme.startsWith("///")) { - _extractDocCommentsFromPartDirective(directive, directiveComments); - } else { - _extractPrecedingCommentsFromPartDirective( - directive, directiveComments); - } - } - } -} - -ImportType _getDirectiveType( - String directive, - FilePathCollectorResult collectorResult, - Cfg cfg, -) { - if (directive.contains("library")) { - return ImportType.library; - } else if (directive.contains("part")) { - return ImportType.part; - } else if (directive.contains('dart:')) { - return ImportType.dart; - } else if (directive.contains('package:flutter')) { - return ImportType.flutter; - } else if (directive.contains('package:${cfg.projectName}')) { - return ImportType.project; - } else if (!directive.contains('package:')) { - var fileName = _extractFileName(directive); - var filePath = - collectorResult.allPaths.firstWhere((path) => path.contains(fileName)); - - if (filePath.contains("lib/")) { - return ImportType.project; - } else { - return ImportType.relative; - } - } else { - return ImportType.package; - } -} - -String _extractFileName(String import) { - Uri uri = Uri.parse(_extractPathFromImport(import)); - return uri.pathSegments.last; -} - -String _extractPathFromImport(String importStatement) { - var matches = RegExp(r"'([^']*)'").allMatches(importStatement); - return matches.first.group(1) ?? ''; -} - -void _extractDocCommentsFromLibraryDirective( - LibraryDirective directive, - Map> inputTypeEntry, -) { - log.fine("┠── Extracting doc comments.."); - - _extractDocComments( - directive.toString(), directive.beginToken, inputTypeEntry); -} - -void _extractDocCommentsFromImportDirective( - ImportDirective directive, - Map> inputTypeEntry, -) { - log.fine("┠── Extracting doc comments.."); - - _extractDocComments( - directive.toString(), directive.beginToken, inputTypeEntry); -} - -void _extractDocCommentsFromPartDirective( - PartDirective directive, - Map> inputTypeEntry, -) { - log.fine("┠── Extracting doc comments.."); - - _extractDocComments( - directive.toString(), directive.beginToken, inputTypeEntry); -} - -void _extractDocComments( - String directiveValue, - Token? beginToken, - Map> directiveToComments, -) { - while (beginToken != null) { - if (!_isImportComment(beginToken.lexeme)) { - directiveToComments[directiveValue]!.add(beginToken.lexeme); - } - - beginToken = beginToken.next; - } -} - -void _extractPrecedingCommentsFromImportDirective( - ImportDirective directive, - Map> directiveToComments, -) { - log.fine("┠── Extracting preceding comments.."); - - dynamic precedingComment = directive.beginToken.precedingComments; - - if (precedingComment == null) { - return; - } - - _extractPrecedingComments( - precedingComment, directiveToComments, directive.toString()); -} - -void _extractPrecedingCommentsFromLibraryDirective( - LibraryDirective directive, - Map> directiveToComments, -) { - log.fine("┠── Extracting preceding comments.."); - - dynamic precedingComment = directive.beginToken.precedingComments; - - if (precedingComment == null) { - return; - } - - _extractPrecedingComments( - precedingComment, directiveToComments, directive.toString()); -} - -void _extractPrecedingCommentsFromPartDirective( - PartDirective directive, - Map> directiveToComments, -) { - log.fine("┠── Extracting preceding comments.."); - - Token? precedingComment = directive.beginToken.precedingComments; - - if (precedingComment == null) { - return; - } - - _extractPrecedingComments( - precedingComment, directiveToComments, directive.toString()); -} - -void _extractPrecedingComments( - Token? precedingComment, - Map> directiveToComments, - String directiveValue, -) { - while (precedingComment != null) { - if (!_isImportComment(precedingComment.toString())) { - directiveToComments[directiveValue]!.add(precedingComment.toString()); - } - - precedingComment = precedingComment.next; - } -} - -bool _isImportComment(String comment) { - return comment == Constants.dartImportsComment || - comment == Constants.flutterImportsComment || - comment == Constants.packageImportsComment || - comment == Constants.projectImportsComment || - comment == Constants.relativeProjectImportsComment; -} - -String _sortDirectives( - String path, - Map>> directivesToComments, - Cfg cfg, -) { - var sortedDirectives = ""; - var projectDirectives = directivesToComments[ImportType.project]!; - var convertedProjectDirectives = - _convertProjectImports(path, projectDirectives, cfg); - - var libraryDirectives = directivesToComments[ImportType.library]!; - - sortedDirectives = - _addDirectivesAndComments(sortedDirectives, libraryDirectives, "", cfg); - - var dartDirectives = directivesToComments[ImportType.dart]!; - - sortedDirectives = _addDirectivesAndComments( - sortedDirectives, dartDirectives, Constants.dartImportsComment, cfg); - - var flutterDirectives = directivesToComments[ImportType.flutter]!; - - sortedDirectives = _addDirectivesAndComments(sortedDirectives, - flutterDirectives, Constants.flutterImportsComment, cfg); - - var packageDirectives = directivesToComments[ImportType.package]!; - - sortedDirectives = _addDirectivesAndComments(sortedDirectives, - packageDirectives, Constants.packageImportsComment, cfg); - - sortedDirectives = _addDirectivesAndComments(sortedDirectives, - convertedProjectDirectives, Constants.projectImportsComment, cfg); - - var relativeDirectives = directivesToComments[ImportType.relative]!; - - sortedDirectives = _addDirectivesAndComments(sortedDirectives, - relativeDirectives, Constants.relativeProjectImportsComment, cfg); - - var partDirectives = directivesToComments[ImportType.part]!; - - sortedDirectives = - _addDirectivesAndComments(sortedDirectives, partDirectives, "", cfg); - - return sortedDirectives; -} - -String _addDirectivesAndComments( - String sortedDirectives, - Map> directives, - String directiveTypeComment, - Cfg cfg, -) { - if (directives.isNotEmpty) { - sortedDirectives += "\n"; - - if (cfg.comments && directiveTypeComment.isNotEmpty) { - sortedDirectives += "$directiveTypeComment\n"; - } - - for (var directive in directives.keys) { - var comments = directives[directive]!; - - for (var comment in comments) { - sortedDirectives += "$comment\n"; - } - - sortedDirectives += "$directive\n"; - } - } - - return sortedDirectives; -} - -Map> _convertProjectImports( - String path, - Map> projectDirectives, - Cfg cfg, -) { - log.fine("┠── Processing project imports.."); - - var newProjectImports = >{}; - - for (var directiveValue in projectDirectives.keys) { - var convertedDirectiveValue = ""; - - if (cfg.relative) { - convertedDirectiveValue = - _convertToRelativeProjectImport(path, directiveValue, cfg); - } else { - convertedDirectiveValue = - _convertToPackageProjectImport(path, directiveValue, cfg); - } - - newProjectImports.putIfAbsent( - convertedDirectiveValue, () => projectDirectives[directiveValue]!); - } - - return newProjectImports; -} - -String _convertToPackageProjectImport( - String path, - String directiveValue, - Cfg cfg, -) { - log.fine("┠─── Converting to project import.."); - - if (directiveValue.startsWith("import 'package:${cfg.projectName}")) { - return directiveValue; - } - - if (!directiveValue.contains("lib")) { - directiveValue = directiveValue.replaceFirst("lib/", ""); - } - - if (directiveValue.contains("..")) { - return directiveValue.replaceFirst("..", "package:${cfg.projectName}"); - } else { - return directiveValue.replaceFirst( - "import '", "import 'package:${cfg.projectName}/"); - } -} - -String _convertToRelativeProjectImport( - String path, - String importLine, - Cfg cfg, -) { - log.fine("┠─── Converting to relative project import.."); - - if (importLine.contains("..")) { - return importLine; - } - - if (importLine.contains("'package:${cfg.projectName}")) { - if (!path.contains("lib")) { - return importLine.replaceFirst("package:${cfg.projectName}", "../lib"); - } else { - return importLine.replaceFirst("package:${cfg.projectName}", ".."); - } - } - - return importLine; -} - -bool _areImportsEmpty(Map>> directives) { - for (var importType in directives.keys) { - var entry = directives[importType]; - - if (entry!.isNotEmpty) { - return false; - } - } - - return true; -} diff --git a/pubspec.yaml b/pubspec.yaml index e958638..30f4bdc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: better_imports description: A better imports sorter for your .dart files. -version: 1.1.0 +version: 1.1.1 repository: https://github.com/oppahansi/better_imports executables: diff --git a/test/file_collector_test.dart b/test/file_collector_test.dart index 6603076..afcf077 100644 --- a/test/file_collector_test.dart +++ b/test/file_collector_test.dart @@ -2,9 +2,9 @@ import 'package:test/test.dart'; // Project Imports -import 'package:better_imports/src/file_path_collector.dart'; -import 'package:better_imports/src/cfg.dart'; import 'package:better_imports/src/arg_parser.dart'; +import 'package:better_imports/src/cfg.dart'; +import 'package:better_imports/src/file_paths_collector.dart'; void main() { group("Collector Tests. Test amount of collected files.", () { diff --git a/test/sorter_test.dart b/test/sorter_test.dart index 167d2d2..b6d9c13 100644 --- a/test/sorter_test.dart +++ b/test/sorter_test.dart @@ -7,8 +7,8 @@ import 'package:test/test.dart'; // Project Imports import 'package:better_imports/src/arg_parser.dart'; import 'package:better_imports/src/cfg.dart'; -import 'package:better_imports/src/file_path_collector.dart'; -import 'package:better_imports/src/import_sorter.dart'; +import 'package:better_imports/src/file_paths_collector.dart'; +import 'package:better_imports/src/files_sorter.dart'; // Relative Project Imports import '../res/sorter_fixtures.dart'; @@ -28,6 +28,7 @@ void main() { () { var argResult = argParser.parse([]); var cfg = Cfg(argResult); + cfg.dryRun = true; var collector = FilePathsCollector(cfg: cfg); var collected = collector.collect();