Add tests for most `displayString()` methods.

Significantly improve test coverage of `display_string_builder.dart`.

Fix an error involving a missing space when reading the enclosing
fragment of a local variable declaration.

Change the formatting of `ConstructorElement` to print only the type and
not the name to avoid duplication, as they were the same.

Change the formatting of `TypeAliasElement` to just print the name of
the aliased type, rather than the whole aliased element - as this rarely
provided useful information.

Change-Id: Ie1e4a3649063c2b3662ef7bd21327c17a5b1456b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/441082
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index d505960..a535440 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -112,7 +112,7 @@
 ''');
     var hover = await prepareHover('A() +');
     // element
-    expect(hover.elementDescription, '(new) A A()');
+    expect(hover.elementDescription, '(new) A()');
     // don't show parameter information for binary operators
     expect(hover.parameter, isNull);
   }
@@ -128,7 +128,7 @@
 ''');
     var hover = await prepareHover('A(); // 1');
     // element
-    expect(hover.elementDescription, '(new) A A()');
+    expect(hover.elementDescription, '(new) A()');
     // don't show parameter information for binary operators
     expect(hover.parameter, isNull);
   }
@@ -149,7 +149,7 @@
       expect(hover.length, 'A.named'.length);
       // element
       expect(hover.dartdoc, 'my doc');
-      expect(hover.elementDescription, 'A A.named()');
+      expect(hover.elementDescription, 'A.named()');
       expect(hover.elementKind, 'constructor');
     }
 
@@ -176,7 +176,7 @@
       expect(hover.length, 'A.named'.length);
       // element
       expect(hover.dartdoc, 'my doc');
-      expect(hover.elementDescription, 'A A.named()');
+      expect(hover.elementDescription, 'A.named()');
       expect(hover.elementKind, 'constructor');
     }
 
@@ -207,7 +207,7 @@
     expect(hover.containingLibraryName, 'package:test/test.dart');
     expect(hover.containingLibraryPath, testFile.path);
     expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, '(const) A A(int i)');
+    expect(hover.elementDescription, '(const) A(int i)');
     expect(hover.elementKind, 'constructor');
     // types
     expect(hover.staticType, isNull);
@@ -231,7 +231,7 @@
     expect(hover.containingLibraryName, 'package:test/test.dart');
     expect(hover.containingLibraryPath, testFile.path);
     expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, '(new) A A()');
+    expect(hover.elementDescription, '(new) A()');
     expect(hover.elementKind, 'constructor');
     // types
     expect(hover.staticType, isNull);
@@ -256,7 +256,7 @@
     expect(hover.containingLibraryName, 'package:test/test.dart');
     expect(hover.containingLibraryPath, testFile.path);
     expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, 'A A()');
+    expect(hover.elementDescription, 'A()');
     expect(hover.elementKind, 'constructor');
     // types
     expect(hover.staticType, isNull);
@@ -280,7 +280,7 @@
       expect(hover.containingLibraryName, 'package:test/test.dart');
       expect(hover.containingLibraryPath, testFile.path);
       expect(hover.dartdoc, isNull);
-      expect(hover.elementDescription, 'A<String> A()');
+      expect(hover.elementDescription, 'A<String>()');
       expect(hover.elementKind, 'constructor');
       // types
       expect(hover.staticType, isNull);
@@ -324,7 +324,7 @@
     expect(hover.containingLibraryPath, testFile.path);
     expect(hover.containingClassDescription, 'A');
     expect(hover.dartdoc, 'doc aaa\ndoc bbb');
-    expect(hover.elementDescription, 'A<double> A.named()');
+    expect(hover.elementDescription, 'A<double>.named()');
     expect(hover.elementKind, 'constructor');
     // types
     expect(hover.staticType, isNull);
@@ -351,7 +351,7 @@
     expect(hover.containingLibraryPath, testFile.path);
     expect(hover.containingClassDescription, 'A');
     expect(hover.dartdoc, 'doc aaa\ndoc bbb');
-    expect(hover.elementDescription, 'A<double> A()');
+    expect(hover.elementDescription, 'A<double>()');
     expect(hover.elementKind, 'constructor');
     // types
     expect(hover.staticType, isNull);
@@ -378,7 +378,7 @@
     expect(hover.containingLibraryPath, testFile.path);
     expect(hover.containingClassDescription, 'A');
     expect(hover.dartdoc, 'doc aaa\ndoc bbb');
-    expect(hover.elementDescription, 'A<double> A()');
+    expect(hover.elementDescription, 'A<double>()');
     expect(hover.elementKind, 'constructor');
     // types
     expect(hover.staticType, isNull);
@@ -401,7 +401,7 @@
     expect(hover.containingLibraryPath, testFile.path);
     expect(hover.containingClassDescription, 'A');
     expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, 'A<double> A()');
+    expect(hover.elementDescription, 'A<double>()');
     expect(hover.elementKind, 'constructor');
     // types
     expect(hover.staticType, isNull);
@@ -1786,7 +1786,7 @@
     var hover = await prepareHover('A');
     _assertHover(
       hover,
-      elementDescription: 'typedef A = void Function(int a)',
+      elementDescription: 'typedef A = void Function(int)',
       elementKind: 'type alias',
     );
   }
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
index 2393a15..4faa988 100644
--- a/pkg/analysis_server/test/lsp/hover_test.dart
+++ b/pkg/analysis_server/test/lsp/hover_test.dart
@@ -222,7 +222,7 @@
 ''';
     var expected = '''
 ```dart
-(new) A A.named()
+(new) A.named()
 ```
 Declared in `A` in _package:test/main.dart_.''';
     await assertStringContents(content, equals(expected));
@@ -239,7 +239,7 @@
 ''';
     var expected = '''
 ```dart
-(const) A A.named()
+(const) A.named()
 ```
 Declared in `A` in _package:test/main.dart_.''';
     await assertStringContents(content, equals(expected));
@@ -254,7 +254,7 @@
 ''';
     var expected = '''
 ```dart
-(new) A A()
+(new) A()
 ```
 Declared in `A` in _package:test/main.dart_.''';
     await assertStringContents(content, equals(expected));
@@ -271,7 +271,7 @@
 ''';
     var expected = '''
 ```dart
-(const) A A()
+(const) A()
 ```
 Declared in `A` in _package:test/main.dart_.''';
     await assertStringContents(content, equals(expected));
@@ -883,7 +883,7 @@
       1,
       2,
     ]);
-    ''', contains('String String.fromCharCodes('));
+    ''', contains('String.fromCharCodes('));
 
   Future<void> test_recordLiteral_named() => assertStringContents(r'''
 void f(({int f1, int f2}) r) {
@@ -921,7 +921,7 @@
     ''',
     startsWith('''
 ```dart
-(new) Foo Foo(
+(new) Foo(
   String arg1,
   String arg2, [
   String? arg3,
@@ -941,7 +941,7 @@
     ''',
     startsWith('''
 ```dart
-(new) Foo Foo(String a, String b)
+(new) Foo(String a, String b)
 ```'''),
   );
 
diff --git a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
index 766a609..50ca0b0 100644
--- a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
@@ -70,7 +70,10 @@
   void writeConstructorElement(ConstructorElementMixin2 element) {
     _writeType(element.returnType);
 
-    _write(' ${element.displayName}');
+    var displayName = element.name ?? '<null-name>';
+    if (displayName != 'new') {
+      _write('.$displayName');
+    }
 
     _writeFormalParameters(
       element.formalParameters,
@@ -130,8 +133,7 @@
     _writeTypeParameters(element.typeParameters);
     _write('(');
     _writeType(element.representation.type);
-    _write(' ');
-    _write(element.representation.name ?? '<null-name}>');
+    _write(' ${element.representation.name ?? '<null-name>'}');
     _write(')');
 
     _writeTypesIfNotEmpty(' implements ', element.interfaces);
@@ -195,8 +197,7 @@
   }
 
   void writeLibraryElement(LibraryElementImpl element) {
-    _write('library ');
-    _write('${element.source.uri}');
+    _write('library ${element.uri}');
   }
 
   void writeLibraryExport(LibraryExportImpl element) {
@@ -211,15 +212,14 @@
 
   void writeLocalFunctionElement(LocalFunctionElementImpl element) {
     _writeType(element.returnType);
-    _write(element.name ?? ' <null-name>');
+    _write(' ${element.name ?? '<null-name>'}');
     _writeTypeParameters(element.typeParameters);
     _writeFormalParameters(element.formalParameters, forElement: true);
   }
 
   void writeMethodElement(MethodElementImpl element) {
     _writeType(element.returnType);
-    _write(' ');
-    _write(element.name ?? '<null-name>');
+    _write(' ${element.name ?? '<null-name>'}');
     _writeTypeParameters(element.typeParameters);
     _writeFormalParameters(
       element.formalParameters,
@@ -256,11 +256,7 @@
   void writePrefixElement(PrefixElementImpl element) {
     var libraryImports = element.imports;
     var displayName = element.displayName;
-    if (libraryImports.isEmpty) {
-      _write('as ');
-      _write(displayName);
-      return;
-    }
+
     var first = libraryImports.first;
     _write("import '${first.libraryName}' as $displayName;");
     if (libraryImports.length == 1) {
@@ -316,8 +312,7 @@
 
   void writeTopLevelFunctionElement(TopLevelFunctionElementImpl element) {
     _writeType(element.returnType);
-    _write(' ');
-    _write(element.name ?? ' <null-name>');
+    _write(' ${element.name ?? '<null-name>'}');
     _writeTypeParameters(element.typeParameters);
     _writeFormalParameters(
       element.formalParameters,
@@ -331,13 +326,7 @@
     _write(element.displayName);
     _writeTypeParameters(element.typeParameters);
     _write(' = ');
-
-    var aliasedElement = element.aliasedElement;
-    if (aliasedElement != null) {
-      aliasedElement.appendTo(this);
-    } else {
-      _writeType(element.aliasedType);
-    }
+    _writeType(element.aliasedType);
   }
 
   void writeTypeParameterElement(TypeParameterElementImpl element) {
@@ -404,10 +393,8 @@
   }
 
   void _writeDirectiveUri(DirectiveUri uri) {
-    if (uri is DirectiveUriWithUnitImpl) {
-      _write('unit ${uri.libraryFragment.source.uri}');
-    } else if (uri is DirectiveUriWithSourceImpl) {
-      _write('source ${uri.source}');
+    if (uri is DirectiveUriWithSourceImpl) {
+      _write('${uri.source.uri}');
     } else {
       _write('<unknown>');
     }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 76cb082..ebce8ef 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1795,6 +1795,20 @@
   @Deprecated('Use metadata instead')
   @override
   MetadataImpl get metadata2 => metadata;
+
+  /// Append a textual representation to the given [builder].
+  void appendTo(ElementDisplayStringBuilder builder);
+
+  String displayString() {
+    var builder = ElementDisplayStringBuilder(preferTypeAlias: false);
+    appendTo(builder);
+    return builder.toString();
+  }
+
+  @override
+  String toString() {
+    return displayString();
+  }
 }
 
 abstract class ElementImpl implements Element {
@@ -6126,6 +6140,11 @@
   LibraryElementImpl? get exportedLibrary2 {
     return exportedLibrary;
   }
+
+  @override
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeLibraryExport(this);
+  }
 }
 
 /// A concrete implementation of [LibraryFragment].
@@ -6706,6 +6725,11 @@
   @Deprecated('Use prefix instead')
   @override
   PrefixFragment? get prefix2 => prefix;
+
+  @override
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeLibraryImport(this);
+  }
 }
 
 /// The provider for the lazily created `loadLibrary` function.
@@ -8226,6 +8250,11 @@
     }
     return null;
   }
+
+  @override
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writePartInclude(this);
+  }
 }
 
 class PatternVariableElementImpl extends LocalVariableElementImpl
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element2.dart b/pkg/analyzer/lib/src/test_utilities/find_element2.dart
index 225a159..56daf50 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element2.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element2.dart
@@ -162,6 +162,7 @@
   }
 
   @override
+  // TODO(fshcheglov): rename to formalParameter()
   FormalParameterElement parameter(String name) {
     FormalParameterElement? result;
 
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 1f54f8f..a0d18d7 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -3233,7 +3233,7 @@
     assertType(typeName.type, 'A<T2, U2>');
 
     var constructorMember = redirected.element!;
-    expect(constructorMember.displayString(), 'A<T2, U2> A.named()');
+    expect(constructorMember.displayString(), 'A<T2, U2>.named()');
     expect(redirected.name!.element, constructorMember);
   }
 
@@ -3266,7 +3266,7 @@
     assertType(typeName.type, 'A<T2, U2>');
 
     expect(redirected.name, isNull);
-    expect(redirected.element!.displayString(), 'A<T2, U2> A()');
+    expect(redirected.element!.displayString(), 'A<T2, U2>()');
   }
 
   test_redirectingConstructor_propagation() async {
diff --git a/pkg/analyzer/test/src/dart/element/display_string_test.dart b/pkg/analyzer/test/src/dart/element/display_string_test.dart
index 9ca721e..bb08009 100644
--- a/pkg/analyzer/test/src/dart/element/display_string_test.dart
+++ b/pkg/analyzer/test/src/dart/element/display_string_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -108,6 +110,39 @@
 ])''');
   }
 
+  test_maybeWriteTypeAlias() async {
+    await assertNoErrorsInCode(r'''
+typedef A = int;
+A f() {
+  throw 0;
+}
+''');
+    var element = findElement2.function('f');
+    expect(element.displayString(preferTypeAlias: true), 'A f()');
+  }
+
+  test_maybeWriteTypeAlias_nullable() async {
+    await assertNoErrorsInCode(r'''
+typedef A = int;
+A? f() {
+  throw 0;
+}
+''');
+    var element = findElement2.function('f');
+    expect(element.displayString(preferTypeAlias: true), 'A? f()');
+  }
+
+  test_maybeWriteTypeAlias_typeArguments() async {
+    await assertNoErrorsInCode(r'''
+typedef A<T> = List<T>;
+A<int> f() {
+  throw 0;
+}
+''');
+    var element = findElement2.function('f');
+    expect(element.displayString(preferTypeAlias: true), 'A<int> f()');
+  }
+
   test_property_getter() async {
     await assertNoErrorsInCode(r'''
 String get a => '';
@@ -142,4 +177,547 @@
     // multiline: true.
     expect(multiLine, 'String? m(String? a, [String? b])');
   }
+
+  test_writeClassElement_base() async {
+    await assertNoErrorsInCode(r'''
+base class A {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'base class A');
+  }
+
+  test_writeClassElement_extends() async {
+    await assertNoErrorsInCode(r'''
+class B {}
+class A extends B {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'class A extends B');
+  }
+
+  test_writeClassElement_final() async {
+    await assertNoErrorsInCode(r'''
+final class A {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'final class A');
+  }
+
+  test_writeClassElement_implements() async {
+    await assertNoErrorsInCode(r'''
+class B {}
+class A implements B {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'class A implements B');
+  }
+
+  test_writeClassElement_interface() async {
+    await assertNoErrorsInCode(r'''
+interface class A {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'interface class A');
+  }
+
+  test_writeClassElement_mixin() async {
+    await assertNoErrorsInCode(r'''
+mixin class A {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'mixin class A');
+  }
+
+  test_writeClassElement_sealed() async {
+    await assertNoErrorsInCode(r'''
+sealed class A {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'sealed class A');
+  }
+
+  test_writeClassElement_superInterfaces() async {
+    await assertNoErrorsInCode(r'''
+class E {}
+mixin W {}
+class I {}
+class A extends E with W implements I {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'class A extends E with W implements I');
+  }
+
+  test_writeClassElement_typeParameters() async {
+    await assertNoErrorsInCode(r'''
+class A<T, S extends num>{}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'class A<T, S extends num>');
+  }
+
+  test_writeClassElement_with() async {
+    await assertNoErrorsInCode(r'''
+mixin B {}
+class A with B {}
+''');
+    var element = findElement2.class_('A');
+    expect(element.displayString(), 'class A with B');
+  }
+
+  test_writeConstructorElement_explicit_named() async {
+    await assertNoErrorsInCode(r'''
+final class A {
+  A.named();
+}
+''');
+    var element = findElement2.constructor('named');
+    expect(element.displayString(), 'A.named()');
+  }
+
+  test_writeConstructorElement_explicit_unnamed() async {
+    await assertNoErrorsInCode(r'''
+final class A {
+  A();
+}
+''');
+    var element = findElement2.unnamedConstructor('A');
+    expect(element.displayString(), 'A()');
+  }
+
+  test_writeConstructorElement_formalParameters() async {
+    await assertNoErrorsInCode(r'''
+final class A {
+  A(int a, bool b, {String? c});
+}
+''');
+    var element = findElement2.unnamedConstructor('A');
+    expect(element.displayString(), 'A(int a, bool b, {String? c})');
+  }
+
+  test_writeConstructorElement_synthetic() async {
+    await assertNoErrorsInCode(r'''
+final class A {}
+''');
+    var element = findElement2.unnamedConstructor('A');
+    expect(element.displayString(), 'A()');
+  }
+
+  test_writeDirectiveUri() async {
+    await assertErrorsInCode(
+      r'''
+import 'src/f.dart';
+''',
+      [error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 12)],
+    );
+    var import =
+        findElement2.libraryFragment.libraryImports[0] as LibraryImportImpl;
+    expect(import.displayString(), "import package:test/src/f.dart");
+  }
+
+  test_writeDynamicElement() async {
+    var element = DynamicElementImpl.instance;
+    expect(element.displayString(), 'dynamic');
+  }
+
+  test_writeDynamicType() async {
+    await assertNoErrorsInCode(r'''
+void f(x) {}
+''');
+    var element = findElement2.parameter('x');
+    expect(element.displayString(), 'dynamic x');
+  }
+
+  test_writeEnumElement() async {
+    await assertNoErrorsInCode(r'''
+enum E {a, b}
+''');
+    var element = findElement2.enum_('E');
+    expect(element.displayString(), 'enum E');
+  }
+
+  test_writeEnumElement_implements() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+enum E implements A {a, b}
+''');
+    var element = findElement2.enum_('E');
+    expect(element.displayString(), 'enum E implements A');
+  }
+
+  test_writeEnumElement_mixin() async {
+    await assertNoErrorsInCode(r'''
+mixin M {}
+enum E with M {a, b}
+''');
+    var element = findElement2.enum_('E');
+    expect(element.displayString(), 'enum E with M');
+  }
+
+  test_writeEnumElement_superInterfaces() async {
+    await assertNoErrorsInCode(r'''
+mixin M {}
+class C {}
+enum E with M implements C {a, b}
+''');
+    var element = findElement2.enum_('E');
+    expect(element.displayString(), 'enum E with M implements C');
+  }
+
+  test_writeEnumElement_typeParameters() async {
+    await assertNoErrorsInCode(r'''
+enum E<T> {a, b}
+''');
+    var element = findElement2.enum_('E');
+    expect(element.displayString(), 'enum E<T>');
+  }
+
+  test_writeFormalParameterElement_isNamed() async {
+    await assertNoErrorsInCode(r'''
+void f({required int? a}){}
+''');
+    var element = findElement2.parameter('a');
+    expect(element.displayString(), '{required int? a}');
+  }
+
+  test_writeFormalParameterElement_isOptionalPositional() async {
+    await assertNoErrorsInCode(r'''
+void f([int? a]){}
+''');
+    var element = findElement2.parameter('a');
+    expect(element.displayString(), '[int? a]');
+  }
+
+  test_writeGenericFunctionTypeElement() async {
+    await assertNoErrorsInCode(r'''
+void Function(int a)? f;
+''');
+    var tf = findNode.singleGenericFunctionType.declaredFragment!;
+    expect(tf.element.displayString(), 'void Function(int a)');
+  }
+
+  test_writeInvalidType() async {
+    await resolveTestCode(r'''
+nonexistentType a;
+''');
+    var element = findElement2.topVar('a');
+    expect(element.displayString(), 'InvalidType a');
+  }
+
+  test_writeLabelElement() async {
+    await assertErrorsInCode(
+      r'''
+void f() {
+  f: 0;
+}
+''',
+      [error(WarningCode.UNUSED_LABEL, 13, 2)],
+    );
+    var element = findElement2.label('f');
+    expect(element.displayString(), 'f');
+  }
+
+  test_writeLibraryElement() async {
+    await assertNoErrorsInCode(r'''
+library f;
+''');
+    var element = findElement2.libraryElement;
+    expect(element.displayString(), 'library package:test/test.dart');
+  }
+
+  test_writeLibraryExport() async {
+    await assertErrorsInCode(
+      r'''
+export 'src/f.dart';
+''',
+      [error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 12)],
+    );
+    var export =
+        findElement2.libraryFragment.libraryExports.single as LibraryExportImpl;
+    expect(export.displayString(), "export package:test/src/f.dart");
+  }
+
+  test_writeLibraryImport() async {
+    await assertErrorsInCode(
+      r'''
+import 'src/f.dart';
+''',
+      [error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 12)],
+    );
+    var import =
+        findElement2.libraryFragment.libraryImports[0] as LibraryImportImpl;
+    expect(import.displayString(), "import package:test/src/f.dart");
+  }
+
+  test_writeLocalFunctionElement() async {
+    await assertErrorsInCode(
+      r'''
+void f() {
+  void g() {}
+}
+''',
+      [error(WarningCode.UNUSED_ELEMENT, 18, 1)],
+    );
+    var element = findElement2.localFunction('g');
+    expect(element.displayString(), "void g()");
+  }
+
+  test_writeLocalFunctionElement_formalParameters() async {
+    await assertErrorsInCode(
+      r'''
+void f() {
+  void g(int a, bool b, {String? c}) {}
+}
+''',
+      [error(WarningCode.UNUSED_ELEMENT, 18, 1)],
+    );
+    var element = findElement2.localFunction('g');
+    expect(element.displayString(), "void g(int a, bool b, {String? c})");
+  }
+
+  test_writeLocalFunctionElement_typeParameters() async {
+    await assertErrorsInCode(
+      r'''
+void f() {
+  void g<T, S extends num>() {}
+}
+''',
+      [error(WarningCode.UNUSED_ELEMENT, 18, 1)],
+    );
+    var element = findElement2.localFunction('g');
+    expect(element.displayString(), "void g<T, S extends num>()");
+  }
+
+  test_writeMixinElement() async {
+    await assertNoErrorsInCode(r'''
+mixin M {}
+''');
+    var element = findElement2.mixin('M');
+    expect(element.displayString(), "mixin M on Object");
+  }
+
+  test_writeMixinElement_base() async {
+    await assertNoErrorsInCode(r'''
+base mixin M {}
+''');
+    var element = findElement2.mixin('M');
+    expect(element.displayString(), "base mixin M on Object");
+  }
+
+  test_writeMixinElement_implements() async {
+    await assertNoErrorsInCode(r'''
+class A{}
+mixin M implements A {}
+''');
+    var element = findElement2.mixin('M');
+    expect(element.displayString(), "mixin M on Object implements A");
+  }
+
+  test_writeMixinElement_typeParameters() async {
+    await assertNoErrorsInCode(r'''
+mixin M<T, S extends num> {}
+''');
+    var element = findElement2.mixin('M');
+    expect(element.displayString(), "mixin M<T, S extends num> on Object");
+  }
+
+  test_writeNeverElement() async {
+    var element = NeverElementImpl.instance;
+    expect(element.displayString(), "Never");
+  }
+
+  test_writeNeverType() async {
+    await assertErrorsInCode(
+      r'''
+Never a;
+''',
+      [error(CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_VARIABLE, 6, 1)],
+    );
+    var element = findElement2.topVar('a');
+    expect(element.displayString(), "Never a");
+  }
+
+  test_writePartInclude() async {
+    await assertErrorsInCode(
+      r'''
+part 'src/f.dart';
+''',
+      [error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 5, 12)],
+    );
+    var element =
+        findElement2.libraryFragment.partIncludes.single as PartIncludeImpl;
+    expect(element.displayString(), 'part package:test/src/f.dart');
+  }
+
+  test_writePrefixElement_multipleImports() async {
+    await assertErrorsInCode(
+      r'''
+import 'src/f.dart' as a;
+import 'src/bar.dart' as a;
+''',
+      [
+        error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 12),
+        error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 33, 14),
+      ],
+    );
+    var prefix = findElement2.prefix('a');
+    expect(
+      prefix.displayString(),
+      "import 'src/f.dart' as a;\nimport 'src/bar.dart' as a;",
+    );
+  }
+
+  test_writePrefixElement_singleImport() async {
+    await assertErrorsInCode(
+      r'''
+import 'src/f.dart' as a;
+''',
+      [error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 12)],
+    );
+    var prefix = findElement2.prefix('a');
+    expect(prefix.displayString(), "import 'src/f.dart' as a;");
+  }
+
+  test_writeRecordType_named() async {
+    await assertNoErrorsInCode(r'''
+typedef A = ({int a, String b});
+''');
+    var typeAlias = findElement2.typeAlias('A');
+    expect(typeAlias.displayString(), 'typedef A = ({int a, String b})');
+  }
+
+  test_writeRecordType_nullable() async {
+    await assertNoErrorsInCode(r'''
+typedef A = (int, String)?;
+''');
+    var typeAlias = findElement2.typeAlias('A');
+    expect(typeAlias.displayString(), 'typedef A = (int, String)?');
+  }
+
+  test_writeRecordType_positional() async {
+    await assertNoErrorsInCode(r'''
+typedef A = (int, String);
+''');
+    var typeAlias = findElement2.typeAlias('A');
+    expect(typeAlias.displayString(), 'typedef A = (int, String)');
+  }
+
+  test_writeRecordType_positionalAndNamed() async {
+    await assertNoErrorsInCode(r'''
+typedef A = (int, String, {bool flag});
+''');
+    var typeAlias = findElement2.typeAlias('A');
+    expect(typeAlias.displayString(), 'typedef A = (int, String, {bool flag})');
+  }
+
+  test_writeRecordType_singlePositional() async {
+    await assertNoErrorsInCode(r'''
+typedef A = (int,);
+''');
+    var typeAlias = findElement2.typeAlias('A');
+    expect(typeAlias.displayString(), 'typedef A = (int,)');
+  }
+
+  test_writeSetterElement() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  set f(int value) {}
+}
+''');
+    var setter = findElement2.setter('f');
+    expect(setter.displayString(), 'set f(int value)');
+  }
+
+  test_writeTopLevelFunctionElement() async {
+    await assertNoErrorsInCode(r'''
+int f() => 0;
+''');
+    var function = findElement2.topFunction('f');
+    expect(function.displayString(), 'int f()');
+  }
+
+  test_writeTopLevelFunctionElement_formalParameters() async {
+    await assertNoErrorsInCode(r'''
+void f(int x, String y) {}
+''');
+    var function = findElement2.topFunction('f');
+    expect(function.displayString(), 'void f(int x, String y)');
+  }
+
+  test_writeTopLevelFunctionElement_typeParameters() async {
+    await assertNoErrorsInCode(r'''
+void f<T, S extends num>() {}
+''');
+    var function = findElement2.topFunction('f');
+    expect(function.displayString(), 'void f<T, S extends num>()');
+  }
+
+  test_writeTypeAliasElement_withAliasedElement() async {
+    await assertNoErrorsInCode(r'''
+typedef A = int;
+''');
+    var typeAlias = findElement2.typeAlias('A');
+    expect(typeAlias.displayString(), 'typedef A = int');
+  }
+
+  test_writeTypeAliasElement_withAliasedElement_typeParameters() async {
+    await assertNoErrorsInCode(r'''
+typedef A<T> = List<T>;
+''');
+    var typeAlias = findElement2.typeAlias('A');
+    expect(typeAlias.displayString(), 'typedef A<out T> = List<T>');
+  }
+
+  test_writeTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+Map<String, double> a = {'A': 1.5};
+''');
+    var element = findElement2.topVar('a');
+    expect(element.displayString(), 'Map<String, double> a');
+  }
+
+  test_writeTypeParameterElement() async {
+    await assertNoErrorsInCode(r'''
+void f<T extends num>() {}
+''');
+    var element = findElement2.typeParameter('T');
+    expect(element.displayString(), 'T extends num');
+  }
+
+  test_writeTypeParameterElement_covariant() async {
+    await assertNoErrorsInCode(r'''
+class A<in T> {}
+''');
+    var elementA = findElement2.typeParameter('T');
+    expect(elementA.displayString(), 'in T');
+  }
+
+  test_writeTypeParameterType() async {
+    await assertNoErrorsInCode(r'''
+void f<T>(T t) {}
+''');
+    var typeAlias = findElement2.parameter('t');
+    expect(typeAlias.displayString(), 'T t');
+  }
+
+  test_writeTypeParameterType_promotedBound() async {
+    await assertNoErrorsInCode(r'''
+void f<T extends num>(T t) {
+  if (t is int) {
+    t;
+  }
+}
+''');
+    var type = findNode.simple('t;').staticType!;
+    expect(type.getDisplayString(), 'T & int');
+  }
+
+  test_writeTypes() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+class B {}
+class C implements A, B {}
+''');
+    var element = findElement2.class_('C');
+    expect(element.displayString(), 'class C implements A, B');
+  }
 }