diagnostic property types support
Adds support for:
* ints
* doubles
* enums
* Strings
Up next: Colors, Iterables, Transforms and a catch-all.
Also note the TODO to change how types are being written (will be needed for Iterables).
See: https://github.com/dart-lang/sdk/issues/38633
Change-Id: I9d545ce9e090059ae330f9ae5dadf8e7d4b373c7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/119725
Commit-Queue: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index 1ce5e03..3c3870b 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -74,7 +74,7 @@
SimpleIdentifier name = node;
final parent = node.parent;
- var type;
+ DartType type;
// Getter.
if (parent is MethodDeclaration) {
@@ -96,53 +96,72 @@
if (type == null) {
return null;
- } else if (type.isDartCoreBool) {
- ClassDeclaration classDeclaration =
- parent.thisOrAncestorOfType<ClassDeclaration>();
- final debugFillProperties =
- classDeclaration.getMethod('debugFillProperties');
- if (debugFillProperties != null) {
- final body = debugFillProperties.body;
- if (body is BlockFunctionBody) {
- BlockFunctionBody functionBody = body;
+ }
- var offset;
- var prefix;
- if (functionBody.block.statements.isEmpty) {
- offset = functionBody.block.leftBracket.offset;
- prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
- } else {
- offset = functionBody.block.statements.last.endToken.offset;
- prefix = utils.getLinePrefix(offset);
- }
+ var constructorInvocation;
+ if (type.isDartCoreBool) {
+ constructorInvocation = 'DiagnosticsProperty<bool>';
+ } else if (type.isDartCoreInt) {
+ constructorInvocation = 'IntProperty';
+ } else if (type.isDartCoreDouble) {
+ constructorInvocation = 'DoubleProperty';
+ } else if (type.isDartCoreString) {
+ constructorInvocation = 'StringProperty';
+ } else if (isEnum(type)) {
+ constructorInvocation = 'EnumProperty';
+ }
- var parameters = debugFillProperties.parameters.parameters;
- var propertiesBuilderName;
- for (var parameter in parameters) {
- if (parameter is SimpleFormalParameter) {
- final type = parameter.type;
- if (type is TypeName) {
- if (type.name.name == 'DiagnosticPropertiesBuilder') {
- propertiesBuilderName = parameter.identifier.name;
- break;
- }
+ // todo (pq): migrate type string generation to within change and use DartEditBuilder.writeType
+
+ if (constructorInvocation == null) {
+ return null;
+ }
+
+ ClassDeclaration classDeclaration =
+ parent.thisOrAncestorOfType<ClassDeclaration>();
+ final debugFillProperties =
+ classDeclaration.getMethod('debugFillProperties');
+ if (debugFillProperties != null) {
+ final body = debugFillProperties.body;
+ if (body is BlockFunctionBody) {
+ BlockFunctionBody functionBody = body;
+
+ var offset;
+ var prefix;
+ if (functionBody.block.statements.isEmpty) {
+ offset = functionBody.block.leftBracket.offset;
+ prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
+ } else {
+ offset = functionBody.block.statements.last.endToken.offset;
+ prefix = utils.getLinePrefix(offset);
+ }
+
+ var parameters = debugFillProperties.parameters.parameters;
+ var propertiesBuilderName;
+ for (var parameter in parameters) {
+ if (parameter is SimpleFormalParameter) {
+ final type = parameter.type;
+ if (type is TypeName) {
+ if (type.name.name == 'DiagnosticPropertiesBuilder') {
+ propertiesBuilderName = parameter.identifier.name;
+ break;
}
}
}
- if (propertiesBuilderName == null) {
- return null;
- }
-
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(utils.getLineNext(offset),
- (DartEditBuilder builder) {
- builder.write(
- "$prefix$propertiesBuilderName.add(DiagnosticsProperty<bool>('${name.name}', ${name.name}));$eol");
- });
- });
- return changeBuilder;
}
+ if (propertiesBuilderName == null) {
+ return null;
+ }
+
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(utils.getLineNext(offset),
+ (DartEditBuilder builder) {
+ builder.write(
+ "$prefix$propertiesBuilderName.add($constructorInvocation('${name.name}', ${name.name}));$eol");
+ });
+ });
+ return changeBuilder;
}
}
@@ -1189,6 +1208,11 @@
return null;
}
+ bool isEnum(DartType type) {
+ final element = type.element;
+ return element is ClassElement && element.isEnum;
+ }
+
@protected
bool setupCompute() {
final locator = NodeLocator(selectionOffset, selectionEnd);
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
index 8912d34..13f5ab3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
@@ -115,14 +115,100 @@
''');
}
+ test_doubleField_debugFillProperties() async {
+ await resolveTestUnit('''
+class A extends Widget {
+ double /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+class A extends Widget {
+ double /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DoubleProperty('field', field));
+ }
+}
+''');
+ }
+
+ test_enumField_debugFillProperties() async {
+ await resolveTestUnit('''
+enum foo {bar}
+class A extends Widget {
+ foo /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+enum foo {bar}
+class A extends Widget {
+ foo /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(EnumProperty('field', field));
+ }
+}
+''');
+ }
+
+ test_intField_debugFillProperties() async {
+ await resolveTestUnit('''
+class A extends Widget {
+ int /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+class A extends Widget {
+ int /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(IntProperty('field', field));
+ }
+}
+''');
+ }
+
+ test_stringField_debugFillProperties() async {
+ await resolveTestUnit('''
+class A extends Widget {
+ String /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+class A extends Widget {
+ String /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(StringProperty('field', field));
+ }
+}
+''');
+ }
+
// todo (pq): tests for no debugFillProperties method
// todo (pq): consider a test for a body w/ no CR
// todo (pq): support for ColorProperty -- for Color
- // todo (pq): support for EnumProperty -- for any enum class
- // todo (pq): support for IntProperty -- int
- // todo (pq): support for DoubleProperty -- double
// todo (pq): support for IterableProperty -- any iterable
- // todo (pq): support for StringProperty -- string
// todo (pq): support for TransformProperty -- Matrix4
// todo (pq): support for DiagnosticsProperty for any T that doesn't match one of the other cases
}