Skip to content

Commit

Permalink
[DAS] Convert into getter as a fix for declaring an extension type field
Browse files Browse the repository at this point in the history
[email protected]

Fixes #59831

Change-Id: I1bc6345a8e5d2b09d511a97bb4f0d97308b2e30b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/402622
Reviewed-by: Phil Quitslund <[email protected]>
Commit-Queue: Phil Quitslund <[email protected]>
Reviewed-by: Konstantin Shcheglov <[email protected]>
Auto-Submit: Felipe Morschel <[email protected]>
  • Loading branch information
FMorschel authored and Commit Queue committed Feb 26, 2025
1 parent e964a4e commit f5dc281
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ abstract final class DartAssistKind {
static const CONVERT_INTO_GETTER = AssistKind(
'dart.assist.convert.finalFieldToGetter',
DartAssistKindPriority.DEFAULT,
'Convert to getter',
"Convert '{0}' to a getter",
);
static const CONVERT_INTO_IS_NOT = AssistKind(
'dart.assist.convert.isNot',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/utilities/extensions/ast.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

class ConvertIntoGetter extends ResolvedCorrectionProducer {
String _memberName = '';

ConvertIntoGetter({required super.context});

@override
Expand All @@ -19,9 +23,18 @@ class ConvertIntoGetter extends ResolvedCorrectionProducer {
CorrectionApplicability
.singleLocation;

@override
List<String>? get assistArguments => [_memberName];

@override
AssistKind get assistKind => DartAssistKind.CONVERT_INTO_GETTER;

@override
List<String>? get fixArguments => assistArguments;

@override
FixKind get fixKind => DartFixKind.CONVERT_INTO_GETTER;

@override
Future<void> compute(ChangeBuilder builder) async {
// Find the enclosing field declaration.
Expand All @@ -43,18 +56,18 @@ class ConvertIntoGetter extends ResolvedCorrectionProducer {
if (fieldDeclaration == null) {
return;
}
// The field must be final and have only one variable.
// The field must have only one variable.
var fieldList = fieldDeclaration.fields;
var finalKeyword = fieldList.keyword;
if (finalKeyword == null || fieldList.variables.length != 1) {
if (fieldList.variables.length != 1) {
return;
}
var field = fieldList.variables.first;
// Prepare the initializer.
var initializer = field.initializer;
if (initializer == null) {
_memberName = field.name.lexeme;
if (_memberName.isEmpty) {
return;
}
// Prepare the initializer.
var initializer = field.initializer;
// Add proposal.
var code = '';
var typeAnnotation = fieldList.type;
Expand All @@ -63,13 +76,25 @@ class ConvertIntoGetter extends ResolvedCorrectionProducer {
}
code += 'get';
code += ' ${field.name.lexeme}';
code += ' => ${utils.getNodeText(initializer)}';
code += ';';
code += ' => ';

var startingKeyword =
fieldList.lateKeyword ??
fieldList.keyword ??
fieldList.type ??
field.name;

var startingKeyword = fieldList.lateKeyword ?? finalKeyword;
var replacementRange = range.startEnd(startingKeyword, fieldDeclaration);
await builder.addDartFileEdit(file, (builder) {
builder.addSimpleReplacement(replacementRange, code);
builder.addReplacement(replacementRange, (builder) {
builder.write(code);
if (initializer == null) {
builder.addSimpleLinkedEdit('initializer', 'null');
builder.write(';');
} else {
builder.write('${utils.getNodeText(initializer)};');
}
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE:
CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT:
status: hasFix
CompileTimeErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD:
status: needsFix
status: hasFix
notes: |-
Remove the field, or add `static`.
CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER:
Expand All @@ -669,10 +669,10 @@ CompileTimeErrorCode.EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_FORMAL_PARAMETER:
Remove it.
CompileTimeErrorCode.EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION:
status: needsFix
CompileTimeErrorCode.EXTENSION_TYPE_DECLARES_INSTANCE_FIELD:
status: hasFix
notes: |-
Remove the field, or add `static`.
CompileTimeErrorCode.EXTENSION_TYPE_DECLARES_INSTANCE_FIELD:
status: needsFix
CompileTimeErrorCode.EXTENSION_TYPE_DECLARES_MEMBER_OF_OBJECT:
status: hasFix
CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_DISALLOWED_TYPE:
Expand Down
5 changes: 5 additions & 0 deletions pkg/analysis_server/lib/src/services/correction/fix.dart
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,11 @@ abstract final class DartFixKind {
DartFixKindPriority.inFile,
'Convert to block body everywhere in file',
);
static const CONVERT_INTO_GETTER = FixKind(
'dart.fix.convert.getter',
DartFixKindPriority.standard,
"Convert '{0}' to a getter",
);
static const CONVERT_FOR_EACH_TO_FOR_LOOP = FixKind(
'dart.fix.convert.toForLoop',
DartFixKindPriority.standard,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import 'package:analysis_server/src/services/correction/dart/convert_flutter_chi
import 'package:analysis_server/src/services/correction/dart/convert_flutter_children.dart';
import 'package:analysis_server/src/services/correction/dart/convert_for_each_to_for_loop.dart';
import 'package:analysis_server/src/services/correction/dart/convert_into_block_body.dart';
import 'package:analysis_server/src/services/correction/dart/convert_into_getter.dart';
import 'package:analysis_server/src/services/correction/dart/convert_into_is_not.dart';
import 'package:analysis_server/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_null_check_to_null_aware_element_or_entry.dart';
Expand Down Expand Up @@ -762,9 +763,15 @@ final _builtInNonLintProducers = <ErrorCode, List<ProducerGenerator>>{
CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT: [
RemoveMethodDeclaration.new,
],
CompileTimeErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD: [
ConvertIntoGetter.new,
],
CompileTimeErrorCode.EXTENSION_TYPE_DECLARES_MEMBER_OF_OBJECT: [
RemoveMethodDeclaration.new,
],
CompileTimeErrorCode.EXTENSION_TYPE_DECLARES_INSTANCE_FIELD: [
ConvertIntoGetter.new,
],
CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER: [
ReplaceWithExtensionName.new,
],
Expand Down
Loading

0 comments on commit f5dc281

Please sign in to comment.