@@ -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.
0 commit comments