Update DartEditBuilderImpl.writeType() to support type aliases.
Change-Id: I560596384e8a8d422a013b6597ca9ab91c2d00df
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182663
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 2445867..9914359 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -852,6 +852,10 @@
);
}
+ if (type is NeverType) {
+ return 'Never';
+ }
+
if (type is TypeParameterType) {
var element = type.element;
if (_isTypeParameterVisible(element)) {
@@ -865,7 +869,7 @@
return 'void';
}
- throw StateError('(${type.runtimeType}) $type');
+ throw UnimplementedError('(${type.runtimeType}) $type');
}
/// Indents given source left or right.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 993cf7e..eb831fc 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -24,6 +24,7 @@
import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:dart_style/dart_style.dart';
+import 'package:meta/meta.dart';
/// A [ChangeBuilder] used to build changes in Dart files.
@Deprecated('Use ChangeBuilder')
@@ -1178,22 +1179,19 @@
}
return false;
}
- // The type `void` does not have an element.
- if (type is VoidType) {
- write('void');
+
+ var aliasElement = type.aliasElement;
+ if (aliasElement != null) {
+ _writeTypeElementArguments(
+ element: aliasElement,
+ typeArguments: type.aliasArguments,
+ methodBeingCopied: methodBeingCopied,
+ );
+ _writeTypeNullability(type);
return true;
}
- var element = type.element;
- // Typedef(s) are represented as GenericFunctionTypeElement(s).
- if (element is GenericFunctionTypeElement &&
- element.typeParameters.isEmpty &&
- element.enclosingElement is FunctionTypeAliasElement) {
- element = element.enclosingElement;
- }
-
- // Just a Function, not FunctionTypeAliasElement.
- if (type is FunctionType && element is! FunctionTypeAliasElement) {
+ if (type is FunctionType) {
if (_writeType(type.returnType, methodBeingCopied: methodBeingCopied)) {
write(' ');
}
@@ -1204,6 +1202,41 @@
return true;
}
+ if (type is InterfaceType) {
+ _writeTypeElementArguments(
+ element: type.element,
+ typeArguments: type.typeArguments,
+ methodBeingCopied: methodBeingCopied,
+ );
+ _writeTypeNullability(type);
+ return true;
+ }
+
+ if (type is NeverType) {
+ write('Never');
+ _writeTypeNullability(type);
+ return true;
+ }
+
+ if (type is TypeParameterType) {
+ write(type.element.name);
+ _writeTypeNullability(type);
+ return true;
+ }
+
+ if (type is VoidType) {
+ write('void');
+ return true;
+ }
+
+ throw UnimplementedError('(${type.runtimeType}) $type');
+ }
+
+ void _writeTypeElementArguments({
+ @required Element element,
+ @required List<DartType> typeArguments,
+ @required ExecutableElement methodBeingCopied,
+ }) {
// Ensure that the element is imported.
_writeLibraryReference(element);
@@ -1212,12 +1245,11 @@
write(name);
// Write type arguments.
- if (type is ParameterizedType) {
- var arguments = type.typeArguments;
+ if (typeArguments.isNotEmpty) {
// Check if has arguments.
var hasArguments = false;
var allArgumentsVisible = true;
- for (var argument in arguments) {
+ for (var argument in typeArguments) {
hasArguments = hasArguments || !argument.isDynamic;
allArgumentsVisible = allArgumentsVisible &&
_getVisibleType(argument, methodBeingCopied: methodBeingCopied) !=
@@ -1226,8 +1258,8 @@
// Write type arguments only if they are useful.
if (hasArguments && allArgumentsVisible) {
write('<');
- for (var i = 0; i < arguments.length; i++) {
- var argument = arguments[i];
+ for (var i = 0; i < typeArguments.length; i++) {
+ var argument = typeArguments[i];
if (i != 0) {
write(', ');
}
@@ -1237,12 +1269,12 @@
write('>');
}
}
+ }
+ void _writeTypeNullability(DartType type) {
if (type.nullabilitySuffix == NullabilitySuffix.question) {
write('?');
}
-
- return true;
}
}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 6d37cfe..430be10 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -106,6 +106,14 @@
var edit = getEdit(builder);
expect(edit.replacement, equalsIgnoringWhitespace('required a'));
}
+
+ Future<void> test_writeType_Never_none() async {
+ await _assertWriteType('Never');
+ }
+
+ Future<void> test_writeType_Never_question() async {
+ await _assertWriteType('Never?');
+ }
}
class DartEditBuilderImplTest extends AbstractContextTest