@@ -11,10 +11,8 @@ import 'package:analyzer/dart/element/type.dart';
1111import 'package:analyzer/diagnostic/diagnostic.dart' ;
1212import 'package:analyzer/error/error.dart' ;
1313import 'package:analyzer/source/source.dart' ;
14- import 'package:analyzer/src/dart/element/extensions.dart' ;
1514import 'package:analyzer/src/dart/element/type.dart' ;
1615import 'package:analyzer/src/diagnostic/diagnostic.dart' ;
17- import 'package:analyzer/src/utilities/extensions/collection.dart' ;
1816import 'package:meta/meta.dart' ;
1917import 'package:source_span/source_span.dart' ;
2018
@@ -170,19 +168,7 @@ class ErrorReporter {
170168 return ;
171169 }
172170
173- if (arguments != null ) {
174- var invalid = arguments
175- .whereNotType <String >()
176- .whereNotType <DartType >()
177- .whereNotType <Element >()
178- .whereNotType <int >()
179- .whereNotType <Uri >();
180- if (invalid.isNotEmpty) {
181- throw ArgumentError ('Tried to format an error using '
182- '${invalid .map ((e ) => e .runtimeType ).join (', ' )}' );
183- }
184- }
185-
171+ _convertElements (arguments);
186172 contextMessages ?? = [];
187173 contextMessages.addAll (_convertTypeNames (arguments));
188174 _errorListener.onError (
@@ -348,76 +334,92 @@ class ErrorReporter {
348334 );
349335 }
350336
351- /// Given an array of [arguments] that may contain [DartType] s and [Element] s,
352- /// converts the types and elements into strings by using the display names of
353- /// each, unless there are two or more types or elements with the same display
354- /// names, in which case the extended display names will be used in order to
337+ /// Convert all [Element] s in the [arguments] into their display strings.
338+ void _convertElements (List <Object >? arguments) {
339+ if (arguments == null ) {
340+ return ;
341+ }
342+
343+ for (var i = 0 ; i < arguments.length; i++ ) {
344+ var argument = arguments[i];
345+ if (argument is Element ) {
346+ arguments[i] = argument.getDisplayString ();
347+ } else if (! (argument is String ||
348+ argument is DartType ||
349+ argument is int ||
350+ argument is Uri )) {
351+ throw ArgumentError (
352+ 'Tried to format an error using ${argument .runtimeType }' );
353+ }
354+ }
355+ }
356+
357+ /// Given an array of [arguments] that is expected to contain two or more
358+ /// types, convert the types into strings by using the display names of the
359+ /// types, unless there are two or more types with the same names, in which
360+ /// case the extended display names of the types will be used in order to
355361 /// clarify the message.
356362 List <DiagnosticMessage > _convertTypeNames (List <Object ?>? arguments) {
363+ var messages = < DiagnosticMessage > [];
357364 if (arguments == null ) {
358- return const [] ;
365+ return messages ;
359366 }
360367
361- var typeGroups = < String , List <_ToConvert > > {};
362- for (var i = 0 ; i < arguments.length; i++ ) {
368+ Map <String , List <_TypeToConvert >> typeGroups = {};
369+ for (int i = 0 ; i < arguments.length; i++ ) {
363370 var argument = arguments[i];
364371 if (argument is TypeImpl ) {
365- var displayName = argument.getDisplayString (preferTypeAlias: true );
366- var types = typeGroups.putIfAbsent (displayName, () => []);
372+ String displayName = argument.getDisplayString (
373+ preferTypeAlias: true ,
374+ );
375+ List <_TypeToConvert > types =
376+ typeGroups.putIfAbsent (displayName, () => < _TypeToConvert > []);
367377 types.add (_TypeToConvert (i, argument, displayName));
368- } else if (argument is Element ) {
369- var displayName = argument.getDisplayString ();
370- var types = typeGroups.putIfAbsent (displayName, () => []);
371- types.add (_ElementToConvert (i, argument, displayName));
372378 }
373379 }
374-
375- var messages = < DiagnosticMessage > [];
376- for (var typeGroup in typeGroups.values) {
380+ for (List <_TypeToConvert > typeGroup in typeGroups.values) {
377381 if (typeGroup.length == 1 ) {
378- var typeToConvert = typeGroup[0 ];
379- // If the display name of a type is unambiguous, just replace the type
380- // in the arguments list with its display name.
382+ _TypeToConvert typeToConvert = typeGroup[0 ];
381383 arguments[typeToConvert.index] = typeToConvert.displayName;
382- continue ;
383- }
384-
385- var nameToElementMap = < String , Set < Element > > {};
386- for ( var typeToConvert in typeGroup) {
387- for ( var element in typeToConvert.allElements) {
388- var elements = nameToElementMap. putIfAbsent (element.name ! , () => {} );
389- elements. add (element);
384+ } else {
385+ Map < String , Set < Element >> nameToElementMap = {};
386+ for ( _TypeToConvert typeToConvert in typeGroup) {
387+ for ( Element element in typeToConvert. allElements ()) {
388+ Set < Element > elements =
389+ nameToElementMap. putIfAbsent (element.name ! , () => < Element > {});
390+ elements. add (element);
391+ }
390392 }
391- }
392-
393- for (var typeToConvert in typeGroup) {
394- // TODO(brianwilkerson): When clients do a better job of displaying
395- // context messages, remove the extra text added to the buffer.
396- StringBuffer ? buffer;
397- for (var element in typeToConvert.allElements) {
398- var name = element.name! ;
399- var sourcePath = element.source! .fullName;
400- if (nameToElementMap[name]! .length > 1 ) {
401- if (buffer == null ) {
402- buffer = StringBuffer ();
403- buffer.write ('where ' );
404- } else {
405- buffer.write (', ' );
393+ for (_TypeToConvert typeToConvert in typeGroup) {
394+ // TODO(brianwilkerson): When clients do a better job of displaying
395+ // context messages, remove the extra text added to the buffer.
396+ StringBuffer ? buffer;
397+ for (Element element in typeToConvert.allElements ()) {
398+ String name = element.name! ;
399+ if (nameToElementMap[name]! .length > 1 ) {
400+ if (buffer == null ) {
401+ buffer = StringBuffer ();
402+ buffer.write ('where ' );
403+ } else {
404+ buffer.write (', ' );
405+ }
406+ buffer.write ('$name is defined in ${element .source !.fullName }' );
406407 }
407- buffer.write ('$name is defined in $sourcePath ' );
408+ messages.add (DiagnosticMessageImpl (
409+ filePath: element.source! .fullName,
410+ length: element.nameLength,
411+ message: '$name is defined in ${element .source !.fullName }' ,
412+ offset: element.nameOffset,
413+ url: null ));
408414 }
409- messages.add (DiagnosticMessageImpl (
410- filePath: element.source! .fullName,
411- length: element.nameLength,
412- message: '$name is defined in $sourcePath ' ,
413- offset: element.nameOffset,
414- url: null ,
415- ));
416- }
417415
418- arguments[typeToConvert.index] = buffer != null
419- ? '${typeToConvert .displayName } ($buffer )'
420- : typeToConvert.displayName;
416+ if (buffer != null ) {
417+ arguments[typeToConvert.index] =
418+ '${typeToConvert .displayName } ($buffer )' ;
419+ } else {
420+ arguments[typeToConvert.index] = typeToConvert.displayName;
421+ }
422+ }
421423 }
422424 }
423425 return messages;
@@ -451,22 +453,6 @@ class RecordingErrorListener implements AnalysisErrorListener {
451453 }
452454}
453455
454- /// Used by [ErrorReporter._convertTypeNames] to keep track of an error argument
455- /// that is an [Element] , that is being converted to a display string.
456- class _ElementToConvert implements _ToConvert {
457- @override
458- final int index;
459-
460- @override
461- final String displayName;
462-
463- @override
464- final Iterable <Element > allElements;
465-
466- _ElementToConvert (this .index, Element element, this .displayName)
467- : allElements = [element];
468- }
469-
470456/// An [AnalysisErrorListener] that ignores error.
471457class _NullErrorListener implements AnalysisErrorListener {
472458 @override
@@ -475,61 +461,42 @@ class _NullErrorListener implements AnalysisErrorListener {
475461 }
476462}
477463
478- /// Used by [ErrorReporter._convertTypeNames] to keep track of an argument that
479- /// is being converted to a display string.
480- abstract class _ToConvert {
481- /// A list of all elements involved in the [DartType] or [Element] 's display
482- /// string.
483- Iterable <Element > get allElements;
484-
485- /// The argument's display string, to replace the argument in the argument
486- /// list.
487- String get displayName;
488-
489- /// The index of the argument in the argument list.
490- int get index;
491- }
492-
493- /// Used by [ErrorReporter._convertTypeNames] to keep track of an error argument
494- /// that is a [DartType] , that is being converted to a display string.
495- class _TypeToConvert implements _ToConvert {
496- @override
464+ /// Used by `ErrorReporter._convertTypeNames` to keep track of a type that is
465+ /// being converted.
466+ class _TypeToConvert {
497467 final int index;
468+ final DartType type;
469+ final String displayName;
498470
499- final DartType _type ;
471+ List < Element > ? _allElements ;
500472
501- @override
502- final String displayName;
473+ _TypeToConvert (this .index, this .type, this .displayName);
503474
504- @override
505- late final Iterable <Element > allElements = () {
506- var elements = < Element > {};
507-
508- void addElementsFrom (DartType type) {
509- if (type is FunctionType ) {
510- addElementsFrom (type.returnType);
511- for (var parameter in type.parameters) {
512- addElementsFrom (parameter.type);
513- }
514- } else if (type is RecordType ) {
515- for (var parameter in type.fields) {
516- addElementsFrom (parameter.type);
517- }
518- } else if (type is InterfaceType ) {
519- if (elements.add (type.element)) {
520- for (var typeArgument in type.typeArguments) {
521- addElementsFrom (typeArgument);
475+ List <Element > allElements () {
476+ if (_allElements == null ) {
477+ Set <Element > elements = < Element > {};
478+
479+ void addElementsFrom (DartType type) {
480+ if (type is FunctionType ) {
481+ addElementsFrom (type.returnType);
482+ for (ParameterElement parameter in type.parameters) {
483+ addElementsFrom (parameter.type);
484+ }
485+ } else if (type is InterfaceType ) {
486+ if (elements.add (type.element)) {
487+ for (DartType typeArgument in type.typeArguments) {
488+ addElementsFrom (typeArgument);
489+ }
522490 }
523491 }
524492 }
525- }
526493
527- addElementsFrom (_type );
528- return elements.where ((element) {
529- var name = element.name;
530- return name != null && name.isNotEmpty;
531- } );
532- }();
533-
534- _TypeToConvert ( this .index, this ._type, this .displayName);
494+ addElementsFrom (type );
495+ _allElements = elements.where ((element) {
496+ var name = element.name;
497+ return name != null && name.isNotEmpty;
498+ }). toList ( );
499+ }
500+ return _allElements ! ;
501+ }
535502}
0 commit comments