Fix for create constructor for Widget with private fields.

Fixes https://github.com/dart-lang/sdk/issues/56182

Change-Id: I25a94dbb5af5dda4db1fde9494783df215587fd5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/410520
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
This commit is contained in:
Keerti Parthasarathy
2025-02-18 21:48:29 -08:00
committed by Commit Queue
parent c6077da0da
commit dd93f6fae0
2 changed files with 84 additions and 10 deletions
@@ -174,13 +174,19 @@ class CreateConstructorForFinalFields extends ResolvedCorrectionProducer {
),
);
builder.write(' key');
var fieldsForInitializers = <_Field>[];
_writeFlutterParameters(
builder: builder,
variableLists: fixContext.variableLists,
fieldsForInitializers: fieldsForInitializers,
);
builder.write('}) : super(key: key);');
builder.write('}) : ');
if (fieldsForInitializers.isNotEmpty) {
builder.write('${_getInitalizersString(fieldsForInitializers)}, ');
}
builder.write('super(key: key);');
});
});
}
@@ -198,16 +204,29 @@ class CreateConstructorForFinalFields extends ResolvedCorrectionProducer {
builder.write('({');
builder.write('super.key');
var fieldsForInitializers = <_Field>[];
_writeFlutterParameters(
builder: builder,
variableLists: fixContext.variableLists,
fieldsForInitializers: fieldsForInitializers,
);
builder.write('});');
builder.write('})');
if (fieldsForInitializers.isNotEmpty) {
builder.write(' : ${_getInitalizersString(fieldsForInitializers)}');
}
builder.write(';');
});
});
}
String _getInitalizersString(List<_Field> fieldsForInitializers) =>
fieldsForInitializers
.map((field) {
return '${field.fieldName} = ${field.namedFormalParameterName}';
})
.join(', ');
Future<void> _notFlutterNamed({
required _FixContext fixContext,
required NamedCompilationUnitMember containerDeclaration,
@@ -259,12 +278,7 @@ class CreateConstructorForFinalFields extends ResolvedCorrectionProducer {
builder.write('})');
if (fieldsForInitializers.isNotEmpty) {
var code = fieldsForInitializers
.map((field) {
return '${field.fieldName} = ${field.namedFormalParameterName}';
})
.join(', ');
builder.write(' : $code');
builder.write(' : ${_getInitalizersString(fieldsForInitializers)}');
}
builder.write(';');
@@ -332,6 +346,7 @@ class CreateConstructorForFinalFields extends ResolvedCorrectionProducer {
void _writeFlutterParameters({
required DartEditBuilder builder,
required Iterable<VariableDeclarationList> variableLists,
required List<_Field> fieldsForInitializers,
}) {
var fields = _fieldsToWrite(variableLists);
if (fields == null) {
@@ -345,8 +360,15 @@ class CreateConstructorForFinalFields extends ResolvedCorrectionProducer {
if (field.hasNonNullableType) {
builder.write('required ');
}
builder.write('this.');
builder.write(field.fieldName);
if (field.namedFormalParameterName == field.fieldName) {
builder.write('this.');
builder.write(field.fieldName);
} else {
builder.write(utils.getNodeText(field.typeAnnotation));
builder.write(' ');
builder.write(field.namedFormalParameterName);
fieldsForInitializers.add(field);
}
}
}
}
@@ -46,6 +46,31 @@ class Test {
''');
}
Future<void> test_class_flutter() async {
writeTestPackageConfig(flutter: true);
await resolveTestCode('''
import 'package:flutter/widgets.dart';
class Test extends StatelessWidget {
final int _a;
}
''');
await assertHasFix(
'''
import 'package:flutter/widgets.dart';
class Test extends StatelessWidget {
final int _a;
const Test({super.key, required int a}) : _a = a;
}
''',
errorFilter: (error) {
return error.message.contains("'_a' must be initialized");
},
);
}
Future<void> test_class_hasSuperClass_withOptionalNamed() async {
await resolveTestCode('''
class A {
@@ -556,4 +581,31 @@ class MyWidget extends StatelessWidget {
},
);
}
Future<void> test_class_flutter_private_field() async {
writeTestPackageConfig(flutter: true);
await resolveTestCode('''
import 'package:flutter/widgets.dart';
class MyWidget extends StatelessWidget {
final int _a;
final int b;
}
''');
await assertHasFix(
'''
import 'package:flutter/widgets.dart';
class MyWidget extends StatelessWidget {
final int _a;
final int b;
const MyWidget({Key? key, required int a, required this.b}) : _a = a, super(key: key);
}
''',
errorFilter: (error) {
return error.message.contains("'b'");
},
);
}
}