Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 2e51423

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Convert the way function types are displayed to better match the syntax of Dart
Change-Id: Id5068bd52b3a35c70cb0d2ccc735469e2f8a0d3b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103701 Commit-Queue: Brian Wilkerson <[email protected]> Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent da3ead0 commit 2e51423

24 files changed

+613
-562
lines changed

pkg/analysis_server/test/analysis/get_hover_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ main(A a) {
543543
expect(hover.elementKind, 'method');
544544
expect(hover.isDeprecated, isFalse);
545545
// types
546-
expect(hover.staticType, '(int, String) → List<String>');
546+
expect(hover.staticType, 'List<String> Function(int, String)');
547547
expect(hover.propagatedType, isNull);
548548
// no parameter
549549
expect(hover.parameter, isNull);
@@ -594,7 +594,7 @@ f(Stream<int> s) {
594594
expect(hover.isDeprecated, isFalse);
595595
// types
596596
expect(hover.staticType,
597-
'(StreamTransformer<int, dynamic>) → Stream<dynamic>');
597+
'Stream<dynamic> Function(StreamTransformer<int, dynamic>)');
598598
expect(hover.propagatedType, isNull);
599599
// no parameter
600600
expect(hover.parameter, isNull);

pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -582,24 +582,28 @@ foo({String children}) {}
582582
//
583583
addTestSource('main() { int.parse("16", ^);}');
584584
await computeSuggestions();
585-
assertSuggestArgumentsAndTypes(
586-
namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'});
585+
assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {
586+
'radix': 'int',
587+
'onError': 'int Function(String)'
588+
});
587589
}
588590

589591
test_ArgumentList_imported_function_named_param1() async {
590592
//
591593
addTestSource('main() { int.parse("16", r^);}');
592594
await computeSuggestions();
593-
assertSuggestArgumentsAndTypes(
594-
namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'});
595+
assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {
596+
'radix': 'int',
597+
'onError': 'int Function(String)'
598+
});
595599
}
596600

597601
test_ArgumentList_imported_function_named_param2() async {
598602
//
599603
addTestSource('main() { int.parse("16", radix: 7, ^);}');
600604
await computeSuggestions();
601605
assertSuggestArgumentsAndTypes(
602-
namedArgumentsWithTypes: {'onError': '(String) → int'});
606+
namedArgumentsWithTypes: {'onError': 'int Function(String)'});
603607
}
604608

605609
test_ArgumentList_imported_function_named_param2a() async {
@@ -613,9 +617,10 @@ foo({String children}) {}
613617
//
614618
addTestSource('main() { int.parse("16", r^: 16);}');
615619
await computeSuggestions();
616-
assertSuggestArgumentsAndTypes(
617-
namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'},
618-
includeColon: false);
620+
assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {
621+
'radix': 'int',
622+
'onError': 'int Function(String)'
623+
}, includeColon: false);
619624
}
620625

621626
test_ArgumentList_imported_function_named_param_label2() async {
@@ -629,8 +634,10 @@ foo({String children}) {}
629634
//
630635
addTestSource('main() { int.parse("16", ^: 16);}');
631636
await computeSuggestions();
632-
assertSuggestArgumentsAndTypes(
633-
namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'});
637+
assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {
638+
'radix': 'int',
639+
'onError': 'int Function(String)'
640+
});
634641
}
635642

636643
test_ArgumentList_local_constructor_named_fieldFormal_documentation() async {
@@ -886,8 +893,10 @@ main() { new A(^);}''');
886893
f(v,{int radix, int onError(String s)}){}
887894
main() { f("16", ^);}''');
888895
await computeSuggestions();
889-
assertSuggestArgumentsAndTypes(
890-
namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'});
896+
assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {
897+
'radix': 'int',
898+
'onError': 'int Function(String)'
899+
});
891900
}
892901

893902
test_ArgumentList_local_function_named_param1() async {
@@ -896,8 +905,10 @@ main() { f("16", ^);}''');
896905
f(v,{int radix, int onError(String s)}){}
897906
main() { f("16", r^);}''');
898907
await computeSuggestions();
899-
assertSuggestArgumentsAndTypes(
900-
namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'});
908+
assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {
909+
'radix': 'int',
910+
'onError': 'int Function(String)'
911+
});
901912
}
902913

903914
test_ArgumentList_local_function_named_param2() async {
@@ -907,7 +918,7 @@ f(v,{int radix, int onError(String s)}){}
907918
main() { f("16", radix: 7, ^);}''');
908919
await computeSuggestions();
909920
assertSuggestArgumentsAndTypes(
910-
namedArgumentsWithTypes: {'onError': '(String) → int'});
921+
namedArgumentsWithTypes: {'onError': 'int Function(String)'});
911922
}
912923

913924
test_ArgumentList_local_function_named_param2a() async {

pkg/analyzer/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
* Deprecated the `abstract` setter in `ClassElementImpl`, `EnumElementImpl`,
88
`MethodElementImpl`, and `PropertyAccessorElementImpl`. `isAbstract` should
99
be used instead.
10+
* Changed the way function types are displayed from e.g. `(int) -> void` to
11+
`void Function(int)`. This is more consistent with the syntax of Dart, and it
12+
will avoid ambiguities when nullability is added to the type system. This
13+
impacts to value returned by both `FunctionType.displayName` and
14+
`FunctionType.toString`. Client code might be broken if it depends on the
15+
content of the returned value.
1016

1117
## 0.36.3
1218
* Deprecated `AstFactory.compilationUnit`. In a future analyzer release, this

pkg/analyzer/lib/dart/element/type.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import 'package:analyzer/src/generated/type_system.dart' show TypeSystem;
2929
abstract class DartType {
3030
/// Return the name of this type as it should appear when presented to users
3131
/// in contexts such as error messages.
32+
///
33+
/// Clients should not depend on the content of the returned value as it will
34+
/// be changed if doing so would improve the UX.
3235
String get displayName;
3336

3437
/// Return the element representing the declaration of this type, or `null` if

pkg/analyzer/lib/src/dart/element/type.dart

Lines changed: 93 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ class CircularFunctionTypeImpl extends DynamicTypeImpl
275275
@override
276276
TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) => this;
277277

278+
@override
279+
void _appendToWithTypeParameters(StringBuffer buffer,
280+
Set<TypeImpl> visitedTypes, bool withNullability, String typeParameters) {
281+
throw StateError('We should never get here.');
282+
}
283+
278284
@override
279285
void _forEachParameterType(
280286
ParameterKind kind, callback(String name, DartType type)) {
@@ -714,11 +720,11 @@ abstract class FunctionTypeImpl extends TypeImpl implements FunctionType {
714720
@override
715721
void appendTo(StringBuffer buffer, Set<TypeImpl> visitedTypes,
716722
{bool withNullability = false}) {
717-
// TODO(paulberry): update to use the new "Function" syntax to avoid
718-
// ambiguity with NNBD, and eliminate code duplication with
723+
// TODO(paulberry): eliminate code duplication with
719724
// _ElementWriter.writeType. See issue #35818.
720725
if (visitedTypes.add(this)) {
721726
if (typeFormals.isNotEmpty) {
727+
StringBuffer typeParametersBuffer = StringBuffer();
722728
// To print a type with type variables, first make sure we have unique
723729
// variable names to print.
724730
Set<TypeParameterType> freeVariables = new HashSet<TypeParameterType>();
@@ -733,10 +739,10 @@ abstract class FunctionTypeImpl extends TypeImpl implements FunctionType {
733739

734740
List<DartType> instantiateTypeArgs = <DartType>[];
735741
List<DartType> variables = <DartType>[];
736-
buffer.write("<");
742+
typeParametersBuffer.write('<');
737743
for (TypeParameterElement e in typeFormals) {
738744
if (e != typeFormals[0]) {
739-
buffer.write(",");
745+
typeParametersBuffer.write(',');
740746
}
741747
String name = e.name;
742748
int counter = 0;
@@ -751,89 +757,27 @@ abstract class FunctionTypeImpl extends TypeImpl implements FunctionType {
751757
}
752758
TypeParameterTypeImpl t =
753759
new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
754-
t.appendTo(buffer, visitedTypes, withNullability: withNullability);
760+
t.appendTo(typeParametersBuffer, visitedTypes,
761+
withNullability: withNullability);
755762
instantiateTypeArgs.add(t);
756763
variables.add(e.type);
757764
if (e.bound != null) {
758-
buffer.write(" extends ");
765+
typeParametersBuffer.write(' extends ');
759766
TypeImpl renamed =
760767
e.bound.substitute2(instantiateTypeArgs, variables);
761-
renamed.appendTo(buffer, visitedTypes);
768+
renamed.appendTo(typeParametersBuffer, visitedTypes);
762769
}
763770
}
764-
buffer.write(">");
765-
766-
// Instantiate it and print the resulting type. After instantiation, it
767-
// will no longer have typeFormals, so we will continue below.
768-
this
769-
.instantiate(instantiateTypeArgs)
770-
.appendTo(buffer, visitedTypes, withNullability: withNullability);
771-
return;
772-
}
773-
774-
List<DartType> normalParameterTypes = this.normalParameterTypes;
775-
List<DartType> optionalParameterTypes = this.optionalParameterTypes;
776-
Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
777-
DartType returnType = this.returnType;
778-
779-
bool needsComma = false;
780-
void writeSeparator() {
781-
if (needsComma) {
782-
buffer.write(", ");
783-
} else {
784-
needsComma = true;
785-
}
786-
}
787-
788-
void startOptionalParameters() {
789-
if (needsComma) {
790-
buffer.write(", ");
791-
needsComma = false;
792-
}
793-
}
794-
795-
buffer.write("(");
796-
if (normalParameterTypes.isNotEmpty) {
797-
for (DartType type in normalParameterTypes) {
798-
writeSeparator();
799-
(type as TypeImpl)
800-
.appendTo(buffer, visitedTypes, withNullability: withNullability);
801-
}
802-
}
803-
if (optionalParameterTypes.isNotEmpty) {
804-
startOptionalParameters();
805-
buffer.write("[");
806-
for (DartType type in optionalParameterTypes) {
807-
writeSeparator();
808-
(type as TypeImpl)
809-
.appendTo(buffer, visitedTypes, withNullability: withNullability);
810-
}
811-
buffer.write("]");
812-
needsComma = true;
813-
}
814-
if (namedParameterTypes.isNotEmpty) {
815-
startOptionalParameters();
816-
buffer.write("{");
817-
namedParameterTypes.forEach((String name, DartType type) {
818-
writeSeparator();
819-
buffer.write(name);
820-
buffer.write(": ");
821-
(type as TypeImpl)
822-
.appendTo(buffer, visitedTypes, withNullability: withNullability);
823-
});
824-
buffer.write("}");
825-
needsComma = true;
826-
}
827-
buffer.write(")");
828-
buffer.write(ElementImpl.RIGHT_ARROW);
829-
if (returnType == null) {
830-
buffer.write("null");
771+
typeParametersBuffer.write('>');
772+
773+
// Instantiate it and print the resulting type.
774+
this.instantiate(instantiateTypeArgs)._appendToWithTypeParameters(
775+
buffer,
776+
visitedTypes,
777+
withNullability,
778+
typeParametersBuffer.toString());
831779
} else {
832-
(returnType as TypeImpl)
833-
.appendTo(buffer, visitedTypes, withNullability: withNullability);
834-
}
835-
if (withNullability) {
836-
_appendNullability(buffer);
780+
_appendToWithTypeParameters(buffer, visitedTypes, withNullability, '');
837781
}
838782
visitedTypes.remove(this);
839783
} else {
@@ -936,6 +880,76 @@ abstract class FunctionTypeImpl extends TypeImpl implements FunctionType {
936880
FunctionTypeImpl substitute3(List<DartType> argumentTypes) =>
937881
substitute2(argumentTypes, typeArguments);
938882

883+
void _appendToWithTypeParameters(StringBuffer buffer,
884+
Set<TypeImpl> visitedTypes, bool withNullability, String typeParameters) {
885+
List<DartType> normalParameterTypes = this.normalParameterTypes;
886+
List<DartType> optionalParameterTypes = this.optionalParameterTypes;
887+
Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
888+
DartType returnType = this.returnType;
889+
890+
if (returnType == null) {
891+
buffer.write('null');
892+
} else {
893+
(returnType as TypeImpl)
894+
.appendTo(buffer, visitedTypes, withNullability: withNullability);
895+
}
896+
buffer.write(' Function');
897+
buffer.write(typeParameters);
898+
bool needsComma = false;
899+
900+
void writeSeparator() {
901+
if (needsComma) {
902+
buffer.write(', ');
903+
} else {
904+
needsComma = true;
905+
}
906+
}
907+
908+
void startOptionalParameters() {
909+
if (needsComma) {
910+
buffer.write(', ');
911+
needsComma = false;
912+
}
913+
}
914+
915+
buffer.write('(');
916+
if (normalParameterTypes.isNotEmpty) {
917+
for (DartType type in normalParameterTypes) {
918+
writeSeparator();
919+
(type as TypeImpl)
920+
.appendTo(buffer, visitedTypes, withNullability: withNullability);
921+
}
922+
}
923+
if (optionalParameterTypes.isNotEmpty) {
924+
startOptionalParameters();
925+
buffer.write('[');
926+
for (DartType type in optionalParameterTypes) {
927+
writeSeparator();
928+
(type as TypeImpl)
929+
.appendTo(buffer, visitedTypes, withNullability: withNullability);
930+
}
931+
buffer.write(']');
932+
needsComma = true;
933+
}
934+
if (namedParameterTypes.isNotEmpty) {
935+
startOptionalParameters();
936+
buffer.write('{');
937+
namedParameterTypes.forEach((String name, DartType type) {
938+
writeSeparator();
939+
buffer.write(name);
940+
buffer.write(': ');
941+
(type as TypeImpl)
942+
.appendTo(buffer, visitedTypes, withNullability: withNullability);
943+
});
944+
buffer.write('}');
945+
needsComma = true;
946+
}
947+
buffer.write(')');
948+
if (withNullability) {
949+
_appendNullability(buffer);
950+
}
951+
}
952+
939953
/**
940954
* Invokes [callback] for each parameter of [kind] with the parameter's [name]
941955
* and type after any type parameters have been applied.

pkg/analyzer/test/generated/simple_resolver_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ main() {
993993
await resolveTestFile();
994994

995995
var node = findNode.simple('myVar(42)');
996-
assertType(node, '(int) → String');
996+
assertType(node, 'String Function(int)');
997997
}
998998

999999
test_metadata_class() async {

0 commit comments

Comments
 (0)