Skip to content

Commit

Permalink
Version 3.5.0-219.0.dev
Browse files Browse the repository at this point in the history
Merge 3971aa9 into dev
  • Loading branch information
Dart CI committed Jun 4, 2024
2 parents 49b5590 + 3971aa9 commit 9dce57c
Show file tree
Hide file tree
Showing 36 changed files with 555 additions and 186 deletions.
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ vars = {
"typed_data_rev": "d14f9654f7a5d6baa7dcc27691bd0fa56769fb67",
"vector_math_rev": "3c03ac3b370f6d11d943d3f5a933ba6cf2526d85",
"watcher_rev": "c00fc2a6cd869cdebbc52e00af3d912d25745729",
"web_rev": "d7766451f43001276b5493b2261d2973702b8334", # b/343654390
"web_rev": "7604578eb538c471d438608673c037121d95dba5",
"web_socket_channel_rev": "45b8ce9ce9fb5194a24d3dff8913c573fbe7896a",
"webdev_rev": "a97c2a1f074209584e7a6a4923d2ca029411f718",
"webdriver_rev": "f85779edd7c9f66198d4391ed3631db1d97a5b11",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,85 @@ class CreateExtensionMethod extends _CreateExtensionMember {
}
}

class CreateExtensionSetter extends _CreateExtensionMember {
String _setterName = '';

CreateExtensionSetter({
required super.context,
});

@override
List<String> get fixArguments => [_setterName];

@override
FixKind get fixKind => DartFixKind.CREATE_EXTENSION_SETTER;

@override
Future<void> compute(ChangeBuilder builder) async {
var nameNode = node;
if (nameNode is! SimpleIdentifier) {
return;
}
if (!nameNode.inSetterContext()) {
return;
}

_setterName = nameNode.name;

// prepare target
Expression? target;
switch (nameNode.parent) {
case PrefixedIdentifier prefixedIdentifier:
if (prefixedIdentifier.identifier == nameNode) {
target = prefixedIdentifier.prefix;
}
case PropertyAccess propertyAccess:
if (propertyAccess.propertyName == nameNode) {
target = propertyAccess.realTarget;
}
}
if (target == null) {
return;
}

// We need the type for the extension.
var targetType = target.staticType;
if (targetType == null ||
targetType is DynamicType ||
targetType is InvalidType) {
return;
}

// Try to find the type of the field.
var fieldTypeNode = climbPropertyAccess(nameNode);
var fieldType = inferUndefinedExpressionType(fieldTypeNode);

void writeSetter(DartEditBuilder builder) {
builder.writeSetterDeclaration(
_setterName,
nameGroupName: 'NAME',
parameterType: fieldType,
parameterTypeGroupName: 'TYPE',
);
}

var updatedExisting = await _updateExistingExtension(
builder,
targetType,
(extension, builder) {
builder.insertGetter(extension, (builder) {
writeSetter(builder);
});
},
);
if (updatedExisting) {
return;
}

await _addNewExtension(builder, targetType, nameNode, writeSetter);
}
}

abstract class _CreateExtensionMember extends ResolvedCorrectionProducer {
_CreateExtensionMember({
required super.context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
#
# Stats:
# - 42 "needsEvaluation"
# - 351 "needsFix"
# - 400 "hasFix"
# - 348 "needsFix"
# - 403 "hasFix"
# - 516 "noFix"

AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR:
Expand Down Expand Up @@ -2865,13 +2865,9 @@ ParserErrorCode.FINAL_CONSTRUCTOR:
ParserErrorCode.FINAL_ENUM:
status: hasFix
ParserErrorCode.FINAL_METHOD:
status: needsFix
notes: |-
Remove the `final` keyword.
status: hasFix
ParserErrorCode.FINAL_MIXIN:
status: needsFix
notes: |-
Remove the `final` keyword.
status: hasFix
ParserErrorCode.FINAL_MIXIN_CLASS:
status: needsFix
notes: |-
Expand Down Expand Up @@ -2919,9 +2915,7 @@ ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH:
ParserErrorCode.INTERFACE_ENUM:
status: needsEvaluation
ParserErrorCode.INTERFACE_MIXIN:
status: needsFix
notes: |-
Remove the `interface` keyword.
status: hasFix
ParserErrorCode.INTERFACE_MIXIN_CLASS:
status: needsFix
notes: |-
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 @@ -691,6 +691,11 @@ class DartFixKind {
DartFixKindPriority.DEFAULT - 20,
"Create extension method '{0}'",
);
static const CREATE_EXTENSION_SETTER = FixKind(
'dart.fix.create.extension.setter',
DartFixKindPriority.DEFAULT - 20,
"Create extension setter '{0}'",
);
static const CREATE_FIELD = FixKind(
'dart.fix.create.field',
49,
Expand Down
10 changes: 10 additions & 0 deletions pkg/analysis_server/lib/src/services/correction/fix_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,7 @@ final _builtInNonLintProducers = {
],
CompileTimeErrorCode.UNDEFINED_SETTER: [
ChangeTo.getterOrSetter,
CreateExtensionSetter.new,
CreateField.new,
CreateSetter.new,
],
Expand Down Expand Up @@ -1384,9 +1385,18 @@ final _builtInNonLintProducers = {
ParserErrorCode.FINAL_CONSTRUCTOR: [
RemoveExtraModifier.new,
],
ParserErrorCode.FINAL_METHOD: [
RemoveExtraModifier.new,
],
ParserErrorCode.FINAL_MIXIN: [
RemoveExtraModifier.new,
],
ParserErrorCode.GETTER_WITH_PARAMETERS: [
RemoveParametersInGetterDeclaration.new,
],
ParserErrorCode.INTERFACE_MIXIN: [
RemoveExtraModifier.new,
],
ParserErrorCode.INVALID_CONSTANT_PATTERN_BINARY: [
AddConst.new,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ void main() {
defineReflectiveSuite(() {
defineReflectiveTests(CreateExtensionGetterTest);
defineReflectiveTests(CreateExtensionMethodTest);
defineReflectiveTests(CreateExtensionSetterTest);
});
}

Expand Down Expand Up @@ -488,3 +489,193 @@ extension on List<int> {
''');
}
}

@reflectiveTest
class CreateExtensionSetterTest extends FixProcessorTest {
@override
FixKind get kind => DartFixKind.CREATE_EXTENSION_SETTER;

Future<void> test_existingExtension() async {
await resolveTestCode('''
void f() {
''.test = 0;
}
extension on String {}
''');
await assertHasFix('''
void f() {
''.test = 0;
}
extension on String {
set test(int test) {}
}
''');
}

Future<void> test_existingExtension_generic_matching() async {
await resolveTestCode('''
void f(List<int> a) {
a.test = 0;
}
extension E<T> on Iterable<T> {}
''');
await assertHasFix('''
void f(List<int> a) {
a.test = 0;
}
extension E<T> on Iterable<T> {
set test(int test) {}
}
''');
}

Future<void> test_existingExtension_generic_notMatching() async {
await resolveTestCode('''
void f(List<int> a) {
a.test = 0;
}
extension E<K, V> on Map<K, V> {}
''');
await assertHasFix('''
void f(List<int> a) {
a.test = 0;
}
extension on List<int> {
set test(int test) {}
}
extension E<K, V> on Map<K, V> {}
''');
}

Future<void> test_existingExtension_hasMethod() async {
await resolveTestCode('''
void f() {
''.test = 0;
}
extension E on String {
// ignore:unused_element
void foo() {}
}
''');
await assertHasFix('''
void f() {
''.test = 0;
}
extension E on String {
set test(int test) {}
// ignore:unused_element
void foo() {}
}
''');
}

Future<void> test_existingExtension_notGeneric_matching() async {
await resolveTestCode('''
void f() {
''.test = 0;
}
extension on String {}
''');
await assertHasFix('''
void f() {
''.test = 0;
}
extension on String {
set test(int test) {}
}
''');
}

Future<void> test_existingExtension_notGeneric_notMatching() async {
await resolveTestCode('''
void f() {
''.test = 0;
}
extension on int {}
''');
await assertHasFix('''
void f() {
''.test = 0;
}
extension on String {
set test(int test) {}
}
extension on int {}
''');
}

Future<void> test_parent_nothing() async {
await resolveTestCode('''
void f() {
test = 0;
}
''');
await assertNoFix();
}

Future<void> test_parent_prefixedIdentifier() async {
await resolveTestCode('''
void f(String a) {
a.test = 0;
}
''');
await assertHasFix('''
void f(String a) {
a.test = 0;
}
extension on String {
set test(int test) {}
}
''');
}

Future<void> test_parent_propertyAccess_cascade() async {
await resolveTestCode('''
void f(String a) {
a..test = 0;
}
''');
await assertHasFix('''
void f(String a) {
a..test = 0;
}
extension on String {
set test(int test) {}
}
''');
}

Future<void> test_targetType_hasTypeArguments() async {
await resolveTestCode('''
void f(List<int> a) {
a.test = 0;
}
''');
await assertHasFix('''
void f(List<int> a) {
a.test = 0;
}
extension on List<int> {
set test(int test) {}
}
''');
}
}
Loading

0 comments on commit 9dce57c

Please sign in to comment.