-
Notifications
You must be signed in to change notification settings - Fork 24
refactor: migrate named_parameters_ordering #298
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
Merged
solid-illiaaihistov
merged 9 commits into
solid-software:analysis_server_migration
from
solid-illiaaihistov:253-migrate-named_parameters_ordering
Jul 1, 2026
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2e39856
refactor: migrate named_parameters_ordering
4b8d852
refactor: improve named parameters ordering fix to preserve trailing …
3d97b42
fix: prevent incorrect parameter reordering when comments are present…
6550bb6
fix: improve trailing comment detection by iterating through the enti…
4be1427
refactor: extract correction and iterable utilities and optimize name…
09da30e
style: fix doc comment line length in correction_utils.dart
f9b09c1
refactor: simplify pairwise implementation to use indexed element access
f3b77c0
refactor: extract comment handling logic to correction utilities
2da727e
Merge remote-tracking branch 'upstream/analysis_server_migration' int…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
195 changes: 195 additions & 0 deletions
195
lib/src/lints/named_parameters_ordering/fixes/named_parameters_ordering_fix.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,195 @@ | ||
| import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; | ||
| import 'package:analysis_server_plugin/edit/dart/dart_fix_kind_priority.dart'; | ||
| import 'package:analyzer/dart/ast/ast.dart'; | ||
| import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; | ||
| import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; | ||
| import 'package:collection/collection.dart'; | ||
| import 'package:solid_lints/src/common/parameter_parser/analysis_options_loader.dart'; | ||
| import 'package:solid_lints/src/lints/named_parameters_ordering/models/named_parameters_ordering_parameters.dart'; | ||
| import 'package:solid_lints/src/lints/named_parameters_ordering/models/parameter_type.dart'; | ||
| import 'package:solid_lints/src/lints/named_parameters_ordering/named_parameters_ordering_rule.dart'; | ||
| import 'package:solid_lints/src/utils/correction_utils.dart'; | ||
|
|
||
| /// A parameter block: the offsets of a parameter (including leading comments | ||
| /// and indentation) and an optional trailing comment on the same line. | ||
| typedef _ParamBlock = ({int blockStart, int blockEnd, String? trailingComment}); | ||
|
|
||
| /// A Quick fix for [NamedParametersOrderingRule] rule. | ||
| class NamedParametersOrderingFix extends ResolvedCorrectionProducer { | ||
| static const _fixKind = FixKind( | ||
| 'solid_lints.fix.named_parameters_ordering', | ||
| DartFixKindPriority.standard, | ||
| "Sort named parameters", | ||
| ); | ||
|
|
||
| /// Creates a new instance of [NamedParametersOrderingFix]. | ||
| NamedParametersOrderingFix({required super.context}); | ||
|
|
||
| @override | ||
| FixKind get fixKind => _fixKind; | ||
|
|
||
| @override | ||
| CorrectionApplicability get applicability => | ||
| CorrectionApplicability.automatically; | ||
|
|
||
| @override | ||
| Future<void> compute(ChangeBuilder builder) async { | ||
| final parameterList = node.thisOrAncestorOfType<FormalParameterList>(); | ||
| if (parameterList == null) return; | ||
|
|
||
| final namedParams = parameterList.parameters | ||
| .where((p) => p.isNamed) | ||
| .toList(); | ||
| if (namedParams.length < 2) return; | ||
|
|
||
| final parametersOrder = _getParametersOrder(); | ||
|
|
||
| final sortedNamedParams = namedParams.sortedBy( | ||
| (e) => parametersOrder.indexOf(ParameterType.fromParameter(e)), | ||
| ); | ||
|
|
||
| // Check if the order is already correct (if sorting changed nothing) | ||
| final isChanged = !const ListEquality<FormalParameter>().equals( | ||
| namedParams, | ||
| sortedNamedParams, | ||
| ); | ||
| if (!isChanged) return; | ||
|
|
||
| final isMultiline = utils | ||
| .getRangeText(parameterList.sourceRange) | ||
| .contains('\n'); | ||
|
|
||
| final hasComments = namedParams.any( | ||
| (p) => p.beginToken.precedingComments != null, | ||
| ); | ||
|
|
||
| final sourceStart = namedParams.first.offset; | ||
| final sourceEnd = namedParams.last.end; | ||
|
|
||
| if (!isMultiline && !hasComments) { | ||
| // Single-line: no leading comments, simple text replacement | ||
| return builder.addDartFileEdit(file, (builder) { | ||
| builder.addSimpleReplacement( | ||
| utils.createRange(sourceStart, sourceEnd), | ||
| sortedNamedParams | ||
| .map((p) => utils.getRangeText(p.sourceRange)) | ||
| .join(', '), | ||
| ); | ||
| }); | ||
| } | ||
|
|
||
| // Multiline: extract parameter blocks including leading and trailing | ||
| // comments | ||
| final blocks = _extractParamBlocks( | ||
| namedParams, | ||
| parameterList, | ||
| ); | ||
|
|
||
| // Map sorted parameters to their corresponding blocks | ||
| final sortedBlocks = sortedNamedParams | ||
| .map((p) => blocks[namedParams.indexOf(p)]) | ||
| .toList(); | ||
|
|
||
| // Determine if original had a trailing comma after the last param | ||
| final tokenAfterEnd = namedParams.last.endToken.next; | ||
| final hasTrailingComma = tokenAfterEnd?.lexeme == ','; | ||
|
|
||
| // Build replacement text preserving trailing comments | ||
| final replacement = sortedBlocks.expandIndexed((i, e) { | ||
| final isLast = i == sortedBlocks.length - 1; | ||
| final trailingComment = e.trailingComment; | ||
| final text = utils.getTextRange(e.blockStart, e.blockEnd); | ||
| return [ | ||
| text, | ||
| if (!isLast || hasTrailingComma) ',', | ||
| if (trailingComment != null) ' $trailingComment', | ||
| if (!isLast) '\n', | ||
| ]; | ||
| }).join(); | ||
|
|
||
| // Extend range to include the original trailing comma and any trailing | ||
| // comment on the original last parameter's line. | ||
| var rangeEnd = hasTrailingComma ? tokenAfterEnd!.end : sourceEnd; | ||
| final upperBound = | ||
| parameterList.rightDelimiter?.offset ?? | ||
| parameterList.rightParenthesis.offset; | ||
| if (rangeEnd < upperBound) { | ||
| final afterLast = utils.getTextRange(rangeEnd, upperBound); | ||
| final newlineIdx = afterLast.indexOf('\n'); | ||
| if (newlineIdx != -1) { | ||
| rangeEnd += newlineIdx; | ||
| } | ||
| } | ||
|
|
||
| final firstBlockStart = blocks.first.blockStart; | ||
| final targetRange = utils.createRange(firstBlockStart, rangeEnd); | ||
|
|
||
| await builder.addDartFileEdit(file, (builder) { | ||
| builder.addSimpleReplacement(targetRange, replacement); | ||
| }); | ||
| } | ||
|
|
||
| /// Extracts text blocks for each named parameter, including any leading | ||
| /// comments that belong to that parameter, and detects trailing comments | ||
| /// on the same line. | ||
| /// | ||
| /// Trailing comments (e.g., `// comment` after a parameter on the same line) | ||
| /// are attributed to the parameter they follow, not the next parameter. | ||
| List<_ParamBlock> _extractParamBlocks( | ||
| List<FormalParameter> namedParams, | ||
| FormalParameterList parameterList, | ||
| ) { | ||
| final blocks = <_ParamBlock>[]; | ||
|
|
||
| final lowerBound = | ||
| parameterList.leftDelimiter?.end ?? parameterList.leftParenthesis.end; | ||
| final upperBound = | ||
| parameterList.rightDelimiter?.offset ?? | ||
| parameterList.rightParenthesis.offset; | ||
|
|
||
| for (int i = 0; i < namedParams.length; i++) { | ||
| final param = namedParams[i]; | ||
| final int minOffset = i == 0 ? lowerBound : namedParams[i - 1].end; | ||
|
|
||
| final nextParamStart = i < namedParams.length - 1 | ||
| ? namedParams[i + 1].offset | ||
| : upperBound; | ||
| final previousParamEnd = i > 0 ? namedParams[i - 1].end : null; | ||
|
|
||
| final leadingComment = utils.getLeadingComment( | ||
| node: param, | ||
| previousEnd: previousParamEnd, | ||
| ); | ||
| final blockStart = utils.getDeclarationStartOffset( | ||
| node: param, | ||
| leadingComment: leadingComment, | ||
| minOffset: minOffset, | ||
| ); | ||
| final trailingComment = utils.getTrailingComment( | ||
| node: param, | ||
| nextOffset: nextParamStart, | ||
| ); | ||
|
|
||
| blocks.add(( | ||
| blockStart: blockStart, | ||
| blockEnd: param.end, | ||
| trailingComment: trailingComment, | ||
| )); | ||
| } | ||
|
|
||
| return blocks; | ||
| } | ||
|
|
||
| List<ParameterType> _getParametersOrder() { | ||
| final loader = AnalysisOptionsLoader( | ||
| resourceProvider: resourceProvider, | ||
| ); | ||
| final options = loader.getRuleOptionsForFile( | ||
| file, | ||
| NamedParametersOrderingRule.lintName, | ||
| ); | ||
| return options == null | ||
| ? ParameterType.defaultOrder | ||
| : NamedParametersOrderingParameters.fromJson(options).order; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.