// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// 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 'dart:io';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/inference_error.dart';
import 'package:test/test.dart';

import 'resolved_ast_printer.dart';

/// Set this path to automatically replace expectations in invocations of
/// [checkElementText] with the new actual texts.
const String? _testPath = null;

/// The list of replacements that update expectations.
final List<_Replacement> _replacements = [];

/// The cached content of the file with the [_testPath].
String? _testCode;

/// The cache line information for the [_testPath] file.
LineInfo? _testCodeLines;

void applyCheckElementTextReplacements() {
  if (_testPath != null && _replacements.isNotEmpty) {
    _replacements.sort((a, b) => b.offset - a.offset);
    String newCode = _testCode!;
    _replacements.forEach((r) {
      newCode =
          newCode.substring(0, r.offset) + r.text + newCode.substring(r.end);
    });
    File(_testPath!).writeAsStringSync(newCode);
  }
}

/// Write the given [library] elements into the canonical text presentation
/// taking into account the specified 'withX' options. Then compare the
/// actual text with the given [expected] one.
void checkElementText(
  LibraryElement library,
  String expected, {
  bool withCodeRanges = false,
  bool withExportScope = false,
  bool withNonSynthetic = false,
}) {
  var writer = _ElementWriter(
    selfUriStr: '${library.source.uri}',
    withCodeRanges: withCodeRanges,
    withExportScope: withExportScope,
    withNonSynthetic: withNonSynthetic,
  );
  writer.writeLibraryElement(library);

  String actualText = writer.buffer.toString();
  actualText =
      actualText.split('\n').map((line) => line.trimRight()).join('\n');

  if (_testPath != null && actualText != expected) {
    if (_testCode == null) {
      _testCode = File(_testPath!).readAsStringSync();
      _testCodeLines = LineInfo.fromContent(_testCode!);
    }

    try {
      throw 42;
    } catch (e, trace) {
      String traceString = trace.toString();

      // Assuming traceString contains "$_testPath:$invocationLine:$column",
      // figure out the value of invocationLine.

      int testFilePathOffset = traceString.indexOf(_testPath!);
      expect(testFilePathOffset, isNonNegative);

      // Sanity check: there must be ':' after the path.
      expect(traceString[testFilePathOffset + _testPath!.length], ':');

      int lineOffset = testFilePathOffset + _testPath!.length + ':'.length;
      int invocationLine = int.parse(traceString.substring(
          lineOffset, traceString.indexOf(':', lineOffset)));
      int invocationOffset =
          _testCodeLines!.getOffsetOfLine(invocationLine - 1);

      const String rawStringPrefix = "r'''";
      int expectationOffset =
          _testCode!.indexOf(rawStringPrefix, invocationOffset);

      // Sanity check: there must be no other strings or blocks.
      expect(_testCode!.substring(invocationOffset, expectationOffset),
          isNot(anyOf(contains("'"), contains('"'), contains('}'))));

      expectationOffset += rawStringPrefix.length;
      int expectationEnd = _testCode!.indexOf("'''", expectationOffset);

      _replacements.add(
          _Replacement(expectationOffset, expectationEnd, '\n' + actualText));
    }
  }

  // Print the actual text to simplify copy/paste into the expectation.
  // if (actualText != expected) {
  //   print('-------- Actual --------');
  //   print(actualText + '------------------------');
  // }

  expect(actualText, expected);
}

/// Writes the canonical text presentation of elements.
class _ElementWriter {
  final String? selfUriStr;
  final bool withCodeRanges;
  final bool withExportScope;
  final bool withNonSynthetic;
  final StringBuffer buffer = StringBuffer();

  String indent = '';

  _ElementWriter({
    this.selfUriStr,
    required this.withCodeRanges,
    required this.withExportScope,
    required this.withNonSynthetic,
  });

  void writeLibraryElement(LibraryElement e) {
    _writelnWithIndent('library');
    _withIndent(() {
      var name = e.name;
      if (name != null && name.isNotEmpty) {
        _writelnWithIndent('name: $name');
      }

      var nameOffset = e.nameOffset;
      if (nameOffset != -1) {
        _writelnWithIndent('nameOffset: $nameOffset');
      }

      _writeDocumentation(e);
      _writeMetadata(e);

      var imports = e.imports.where((import) => !import.isSynthetic).toList();
      _writeElements('imports', imports, _writeImportElement);

      _writeElements('exports', e.exports, _writeExportElement);

      _writelnWithIndent('definingUnit');
      _withIndent(() {
        _writeUnitElement(e.definingCompilationUnit);
      });

      _writeElements('parts', e.parts, (CompilationUnitElement e) {
        _writelnWithIndent(e.uri!);
        _withIndent(() {
          _writeMetadata(e);
          _writeUnitElement(e);
        });
      });

      if (withExportScope) {
        _writelnWithIndent('exportScope');
        _withIndent(() {
          _writeExportScope(e);
        });
      }
    });
  }

  void _assertNonSyntheticElementSelf(Element element) {
    expect(element.isSynthetic, isFalse);
    expect(element.nonSynthetic, same(element));
  }

  /// Assert that the [accessor] of the [property] is correctly linked to
  /// the same enclosing element as the [property].
  void _assertSyntheticAccessorEnclosing(
      PropertyInducingElement property, PropertyAccessorElement accessor) {
    if (accessor.isSynthetic) {
      // Usually we have a non-synthetic property, and a synthetic accessor.
    } else {
      // But it is possible to have a non-synthetic setter.
      // class A {
      //   final int foo;
      //   set foo(int newValue) {}
      // }
      expect(accessor.isSetter, isTrue);
    }

    expect(accessor.variable, same(property));

    var propertyEnclosing = property.enclosingElement;
    expect(accessor.enclosingElement, same(propertyEnclosing));

    if (propertyEnclosing is CompilationUnitElement) {
      expect(propertyEnclosing.accessors, contains(accessor));
    } else if (propertyEnclosing is ClassElement) {
      expect(propertyEnclosing.accessors, contains(accessor));
    }
  }

  ResolvedAstPrinter _createAstPrinter() {
    return ResolvedAstPrinter(
      selfUriStr: selfUriStr,
      sink: buffer,
      indent: indent,
      withNullability: true,
      withOffsets: true,
    );
  }

  String _getElementLocationString(Element? element) {
    if (element == null || element is MultiplyDefinedElement) {
      return 'null';
    }

    String onlyName(String uri) {
      if (uri.startsWith('file:///')) {
        return uri.substring(uri.lastIndexOf('/') + 1);
      }
      return uri;
    }

    var location = element.location!;
    List<String> components = location.components.toList();
    if (components.isNotEmpty) {
      components[0] = onlyName(components[0]);
    }
    if (components.length >= 2) {
      components[1] = onlyName(components[1]);
      if (components[0] == components[1]) {
        components.removeAt(0);
      }
    }
    return components.join(';');
  }

  String? _typeStr(DartType? type) {
    return type?.getDisplayString(
      withNullability: true,
    );
  }

  void _withIndent(void Function() f) {
    var savedIndent = indent;
    indent = '$savedIndent  ';
    f();
    indent = savedIndent;
  }

  void _writeBodyModifiers(ExecutableElement e) {
    if (e.isAsynchronous) {
      expect(e.isSynchronous, isFalse);
      buffer.write(' async');
    }

    if (e.isSynchronous && e.isGenerator) {
      expect(e.isAsynchronous, isFalse);
      buffer.write(' sync');
    }

    _writeIf(e.isGenerator, '*');
  }

  void _writeClassElement(ClassElement e) {
    _writeIndentedLine(() {
      _writeIf(e.isAbstract && !e.isMixin, 'abstract ');
      _writeIf(!e.isSimplyBounded, 'notSimplyBounded ');

      if (e.isEnum) {
        buffer.write('enum ');
      } else if (e.isMixin) {
        buffer.write('mixin ');
      } else {
        buffer.write('class ');
      }
      _writeIf(e.isMixinApplication, 'alias ');

      _writeName(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);
      _writeTypeParameterElements(e.typeParameters);

      var supertype = e.supertype;
      if (supertype != null &&
          (supertype.element.name != 'Object' || e.mixins.isNotEmpty)) {
        _writeType(supertype, name: 'supertype');
      }

      if (e.isMixin) {
        var superclassConstraints = e.superclassConstraints;
        if (superclassConstraints.isEmpty) {
          throw StateError('At least Object is expected.');
        }
        _writeElements<DartType>(
          'superclassConstraints',
          superclassConstraints,
          _writeType,
        );
      }

      _writeElements<DartType>('mixins', e.mixins, _writeType);
      _writeElements<DartType>('interfaces', e.interfaces, _writeType);

      _writeElements('fields', e.fields, _writePropertyInducingElement);

      var constructors = e.constructors;
      if (e.isEnum) {
        expect(constructors, isEmpty);
      } else {
        expect(constructors, isNotEmpty);
      }
      _writeElements('constructors', constructors, _writeConstructorElement);

      _writeElements('accessors', e.accessors, _writePropertyAccessorElement);
      _writeElements('methods', e.methods, _writeMethodElement);
    });

    _assertNonSyntheticElementSelf(e);
  }

  void _writeCodeRange(Element e) {
    if (withCodeRanges && !e.isSynthetic) {
      e as ElementImpl;
      _writelnWithIndent('codeOffset: ${e.codeOffset}');
      _writelnWithIndent('codeLength: ${e.codeLength}');
    }
  }

  void _writeConstantInitializer(Element e) {
    if (e is ConstVariableElement) {
      var initializer = e.constantInitializer;
      if (initializer != null) {
        _writelnWithIndent('constantInitializer');
        _withIndent(() {
          _writeNode(initializer);
        });
      }
    }
  }

  void _writeConstructorElement(ConstructorElement e) {
    e as ConstructorElementImpl;

    _writeIndentedLine(() {
      _writeIf(e.isSynthetic, 'synthetic ');
      _writeIf(e.isExternal, 'external ');
      _writeIf(e.isConst, 'const ');
      _writeIf(e.isFactory, 'factory ');
      expect(e.isAbstract, isFalse);
      _writeName(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);

      var periodOffset = e.periodOffset;
      var nameEnd = e.nameEnd;
      if (periodOffset != null && nameEnd != null) {
        _writelnWithIndent('periodOffset: $periodOffset');
        _writelnWithIndent('nameEnd: $nameEnd');
      }

      _writeParameterElements(e.parameters);

      _writeElements(
        'constantInitializers',
        e.constantInitializers,
        _writeNode,
      );

      var redirectedConstructor = e.redirectedConstructor;
      if (redirectedConstructor != null) {
        _writeElementReference('redirectedConstructor', redirectedConstructor);
      }

      _writeNonSyntheticElement(e);
    });

    expect(e.isAsynchronous, isFalse);
    expect(e.isGenerator, isFalse);

    if (e.isSynthetic) {
      expect(e.nameOffset, -1);
      expect(e.nonSynthetic, same(e.enclosingElement));
    } else {
      expect(e.nameOffset, isPositive);
    }
  }

  void _writeDocumentation(Element element) {
    var documentation = element.documentationComment;
    if (documentation != null) {
      var str = documentation;
      str = str.replaceAll('\n', r'\n');
      str = str.replaceAll('\r', r'\r');
      _writelnWithIndent('documentationComment: $str');
    }
  }

  void _writeElementReference(String name, Element element) {
    var printer = _createAstPrinter();
    printer.writeElement(name, element);
  }

  void _writeElements<T>(String name, List<T> elements, void Function(T) f) {
    if (elements.isNotEmpty) {
      _writelnWithIndent(name);
      _withIndent(() {
        for (var element in elements) {
          f(element);
        }
      });
    }
  }

  void _writeExportElement(ExportElement e) {
    _writeIndentedLine(() {
      _writeUri(e.exportedLibrary?.source);
    });

    _withIndent(() {
      _writeMetadata(e);
      _writeNamespaceCombinators(e.combinators);
    });

    _assertNonSyntheticElementSelf(e);
  }

  void _writeExportScope(LibraryElement e) {
    var map = e.exportNamespace.definedNames;
    var names = map.keys.toList()..sort();
    for (var name in names) {
      var element = map[name];
      var elementLocationStr = _getElementLocationString(element);
      _writelnWithIndent('$name: $elementLocationStr');
    }
  }

  void _writeExtensionElement(ExtensionElement e) {
    _writeIndentedLine(() {
      _writeName(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);
      _writeTypeParameterElements(e.typeParameters);
      _writeType(e.extendedType, name: 'extendedType');
    });

    _withIndent(() {
      _writeElements('fields', e.fields, _writePropertyInducingElement);
      _writeElements('accessors', e.accessors, _writePropertyAccessorElement);
      _writeElements('methods', e.methods, _writeMethodElement);
    });

    _assertNonSyntheticElementSelf(e);
  }

  void _writeFunctionElement(FunctionElement e) {
    _writeIndentedLine(() {
      _writeIf(e.isExternal, 'external ');
      _writeName(e);
      _writeBodyModifiers(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);
      _writeTypeParameterElements(e.typeParameters);
      _writeParameterElements(e.parameters);
      _writeType(e.returnType, name: 'returnType');
    });

    _assertNonSyntheticElementSelf(e);
  }

  void _writeIf(bool flag, String str) {
    if (flag) {
      buffer.write(str);
    }
  }

  void _writeImportElement(ImportElement e) {
    _writeIndentedLine(() {
      _writeUri(e.importedLibrary?.source);
      _writeIf(e.isDeferred, ' deferred');

      var prefix = e.prefix;
      if (prefix != null) {
        buffer.write(' as ');
        _writeName(prefix);
      }
    });

    _withIndent(() {
      _writeMetadata(e);
      _writeNamespaceCombinators(e.combinators);
    });

    _assertNonSyntheticElementSelf(e);
  }

  void _writeIndentedLine(void Function() f) {
    buffer.write(indent);
    f();
    buffer.writeln();
  }

  void _writelnWithIndent(String line) {
    buffer.write(indent);
    buffer.writeln(line);
  }

  void _writeMetadata(Element element) {
    var annotations = element.metadata;
    if (annotations.isNotEmpty) {
      _writelnWithIndent('metadata');
      _withIndent(() {
        for (var annotation in annotations) {
          annotation as ElementAnnotationImpl;
          _writeNode(annotation.annotationAst);
        }
      });
    }
  }

  void _writeMethodElement(MethodElement e) {
    _writeIndentedLine(() {
      _writeIf(e.isSynthetic, 'synthetic ');
      _writeIf(e.isStatic, 'static ');
      _writeIf(e.isAbstract, 'abstract ');
      _writeIf(e.isExternal, 'external ');

      _writeName(e);
      _writeBodyModifiers(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);
      _writeTypeInferenceError(e);

      _writeTypeParameterElements(e.typeParameters);
      _writeParameterElements(e.parameters);
      _writeType(e.returnType, name: 'returnType');
      _writeNonSyntheticElement(e);
    });

    if (e.isSynthetic && e.enclosingElement is EnumElementImpl) {
      expect(e.name, 'toString');
      expect(e.nonSynthetic, same(e.enclosingElement));
    } else {
      _assertNonSyntheticElementSelf(e);
    }
  }

  void _writeName(Element e) {
    var name = e.displayName;
    buffer.write(name);
    buffer.write(name.isNotEmpty ? ' @' : '@');
    buffer.write(e.nameOffset);
  }

  void _writeNamespaceCombinator(NamespaceCombinator e) {
    _writeIndentedLine(() {
      if (e is ShowElementCombinator) {
        buffer.write('show: ');
        buffer.write(e.shownNames.join(', '));
      } else if (e is HideElementCombinator) {
        buffer.write('hide: ');
        buffer.write(e.hiddenNames.join(', '));
      }
    });
  }

  void _writeNamespaceCombinators(List<NamespaceCombinator> elements) {
    _writeElements('combinators', elements, _writeNamespaceCombinator);
  }

  void _writeNode(AstNode node) {
    buffer.write(indent);
    node.accept(
      _createAstPrinter(),
    );
  }

  void _writeNonSyntheticElement(Element e) {
    if (withNonSynthetic) {
      _writeElementReference('nonSynthetic', e.nonSynthetic);
    }
  }

  void _writeParameterElement(ParameterElement e) {
    _writeIndentedLine(() {
      if (e.isRequiredPositional) {
        buffer.write('requiredPositional ');
      } else if (e.isOptionalPositional) {
        buffer.write('optionalPositional ');
      } else if (e.isRequiredNamed) {
        buffer.write('requiredName ');
      } else if (e.isOptionalNamed) {
        buffer.write('optionalNamed ');
      }

      _writeIf(e.isConst, 'const ');
      _writeIf(e.isCovariant, 'covariant ');
      _writeIf(e.isFinal, 'final ');

      if (e is FieldFormalParameterElement) {
        buffer.write('this.');
      }

      _writeName(e);
    });

    _withIndent(() {
      _writeType(e.type, name: 'type');
      _writeMetadata(e);
      _writeCodeRange(e);
      _writeTypeParameterElements(e.typeParameters);
      _writeParameterElements(e.parameters);
      _writeConstantInitializer(e);
      _writeNonSyntheticElement(e);
    });
  }

  void _writeParameterElements(List<ParameterElement> elements) {
    _writeElements('parameters', elements, _writeParameterElement);
  }

  void _writePropertyAccessorElement(PropertyAccessorElement e) {
    PropertyInducingElement variable = e.variable;
    expect(variable, isNotNull);

    var variableEnclosing = variable.enclosingElement;
    if (variableEnclosing is CompilationUnitElement) {
      expect(variableEnclosing.topLevelVariables, contains(variable));
    } else if (variableEnclosing is ClassElement) {
      expect(variableEnclosing.fields, contains(variable));
    }

    if (e.isGetter) {
      expect(variable.getter, same(e));
      if (variable.setter != null) {
        expect(variable.setter!.variable, same(variable));
      }
    } else {
      expect(variable.setter, same(e));
      if (variable.getter != null) {
        expect(variable.getter!.variable, same(variable));
      }
    }

    if (e.isSynthetic) {
      expect(e.nameOffset, -1);
    } else {
      expect(e.nameOffset, isPositive);
      _assertNonSyntheticElementSelf(e);
    }

    _writeIndentedLine(() {
      _writeIf(e.isSynthetic, 'synthetic ');
      _writeIf(e.isStatic, 'static ');
      _writeIf(e.isAbstract, 'abstract ');
      _writeIf(e.isExternal, 'external ');

      if (e.isGetter) {
        buffer.write('get ');
      } else {
        buffer.write('set ');
      }

      _writeName(e);
      _writeBodyModifiers(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);

      expect(e.typeParameters, isEmpty);
      _writeParameterElements(e.parameters);
      _writeType(e.returnType, name: 'returnType');
      _writeNonSyntheticElement(e);
    });
  }

  void _writePropertyInducingElement(PropertyInducingElement e) {
    DartType type = e.type;
    expect(type, isNotNull);

    if (e.isSynthetic) {
      expect(e.nameOffset, -1);
    } else {
      expect(e.getter, isNotNull);
      _assertSyntheticAccessorEnclosing(e, e.getter!);

      if (e.setter != null) {
        _assertSyntheticAccessorEnclosing(e, e.setter!);
      }

      expect(e.nameOffset, isPositive);
      _assertNonSyntheticElementSelf(e);
    }

    _writeIndentedLine(() {
      _writeIf(e.isSynthetic, 'synthetic ');
      _writeIf(e.isStatic, 'static ');
      _writeIf(e is FieldElementImpl && e.isAbstract, 'abstract ');
      _writeIf(e is FieldElementImpl && e.isCovariant, 'covariant ');
      _writeIf(e is FieldElementImpl && e.isExternal, 'external ');
      _writeIf(e.isLate, 'late ');
      _writeIf(e.isFinal, 'final ');
      _writeIf(e.isConst, 'const ');

      _writeName(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);
      _writeTypeInferenceError(e);
      _writeType(e.type, name: 'type');
      _writeConstantInitializer(e);
      _writeNonSyntheticElement(e);
    });
  }

  void _writeType(DartType type, {String? name}) {
    var typeStr = _typeStr(type);
    if (name != null) {
      _writelnWithIndent('$name: $typeStr');
    } else {
      _writelnWithIndent('$typeStr');
    }

    var aliasElement = type.aliasElement;
    var aliasArguments = type.aliasArguments;
    if (aliasElement is TypeAliasElementImpl && aliasArguments != null) {
      _withIndent(() {
        _createAstPrinter().writeElement('aliasElement', aliasElement);

        _writeElements<DartType>(
          'aliasArguments',
          aliasArguments,
          _writeType,
        );
      });
    }
  }

  void _writeTypeAliasElement(TypeAliasElement e) {
    e as TypeAliasElementImpl;

    _writeIndentedLine(() {
      _writeIf(e.isFunctionTypeAliasBased, 'functionTypeAliasBased ');
      _writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
      _writeName(e);
    });

    _withIndent(() {
      _writeDocumentation(e);
      _writeMetadata(e);
      _writeCodeRange(e);
      _writeTypeParameterElements(e.typeParameters);

      var aliasedType = e.aliasedType;
      _writeType(aliasedType, name: 'aliasedType');
      // TODO(scheglov) https://github.com/dart-lang/sdk/issues/44629
      // TODO(scheglov) Remove it when we stop providing it everywhere.
      if (aliasedType is FunctionType) {
        // ignore: deprecated_member_use_from_same_package
        expect(aliasedType.element, isNull);
      }

      var aliasedElement = e.aliasedElement;
      if (aliasedElement is GenericFunctionTypeElement) {
        final aliasedElement_ = aliasedElement as GenericFunctionTypeElement;
        _writelnWithIndent('aliasedElement: GenericFunctionTypeElement');
        _withIndent(() {
          _writeTypeParameterElements(aliasedElement_.typeParameters);
          _writeParameterElements(aliasedElement_.parameters);
          _writeType(aliasedElement_.returnType, name: 'returnType');
        });
      }
    });

    _assertNonSyntheticElementSelf(e);
  }

  void _writeTypeInferenceError(Element e) {
    TopLevelInferenceError? inferenceError;
    if (e is MethodElementImpl) {
      inferenceError = e.typeInferenceError;
    } else if (e is PropertyInducingElementImpl) {
      inferenceError = e.typeInferenceError;
    }

    if (inferenceError != null) {
      String kindName = inferenceError.kind.toString();
      if (kindName.startsWith('TopLevelInferenceErrorKind.')) {
        kindName = kindName.substring('TopLevelInferenceErrorKind.'.length);
      }
      _writelnWithIndent('typeInferenceError: $kindName');
    }
  }

  void _writeTypeParameterElement(TypeParameterElement e) {
    e as TypeParameterElementImpl;

    _writeIndentedLine(() {
      buffer.write('${e.variance} ');
      _writeName(e);
    });

    _withIndent(() {
      _writeCodeRange(e);

      var bound = e.bound;
      if (bound != null) {
        _writeType(bound, name: 'bound');
      }

      var defaultType = e.defaultType;
      if (defaultType != null) {
        _writeType(defaultType, name: 'defaultType');
      }

      _writeMetadata(e);
    });

    _assertNonSyntheticElementSelf(e);
  }

  void _writeTypeParameterElements(List<TypeParameterElement> elements) {
    _writeElements('typeParameters', elements, _writeTypeParameterElement);
  }

  void _writeUnitElement(CompilationUnitElement e) {
    _writeElements('classes', e.classes, _writeClassElement);
    _writeElements('enums', e.enums, _writeClassElement);
    _writeElements('extensions', e.extensions, _writeExtensionElement);
    _writeElements('mixins', e.mixins, _writeClassElement);
    _writeElements('typeAliases', e.typeAliases, _writeTypeAliasElement);
    _writeElements(
      'topLevelVariables',
      e.topLevelVariables,
      _writePropertyInducingElement,
    );
    _writeElements(
      'accessors',
      e.accessors,
      _writePropertyAccessorElement,
    );
    _writeElements('functions', e.functions, _writeFunctionElement);
  }

  void _writeUri(Source? source) {
    if (source != null) {
      Uri uri = source.uri;
      String uriStr = uri.toString();
      if (uri.isScheme('file')) {
        uriStr = uri.pathSegments.last;
      }
      buffer.write('$uriStr');
    } else {
      buffer.write('<unresolved>');
    }
  }
}

class _Replacement {
  final int offset;
  final int end;
  final String text;

  _Replacement(this.offset, this.end, this.text);
}
