blob: c6d1707f10412cd31f703d1ef277aca2f8c322e0 [file] [log] [blame]
// 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 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/field_name_non_promotability_info.dart';
import 'package:analyzer/src/summary2/export.dart';
import 'package:analyzer/src/summary2/macro_application_error.dart';
import 'package:analyzer/src/summary2/macro_type_location.dart';
import 'package:analyzer/src/task/inference_error.dart';
import 'package:analyzer_utilities/testing/tree_string_sink.dart';
import 'package:collection/collection.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';
import '../../util/element_printer.dart';
import 'resolved_ast_printer.dart';
String getLibraryText({
required LibraryElementImpl library,
required ElementTextConfiguration configuration,
}) {
var buffer = StringBuffer();
var sink = TreeStringSink(
sink: buffer,
indent: '',
);
var elementPrinter = ElementPrinter(
sink: sink,
configuration: configuration.elementPrinterConfiguration,
);
var writer = _ElementWriter(
sink: sink,
elementPrinter: elementPrinter,
configuration: configuration,
);
writer.writeLibraryElement(library);
sink.writeln('-' * 40);
var writer2 = _Element2Writer(
sink: sink,
elementPrinter: elementPrinter,
configuration: configuration,
);
writer2.writeLibraryElement(library);
return buffer.toString();
}
class ElementTextConfiguration {
ElementPrinterConfiguration elementPrinterConfiguration =
ElementPrinterConfiguration();
bool Function(Object) filter;
List<Pattern>? macroDiagnosticMessagePatterns;
bool withAllSupertypes = false;
bool withAugmentedWithoutAugmentation = false;
bool withCodeRanges = false;
bool withConstantInitializers = true;
bool withConstructors = true;
bool withDisplayName = false;
bool withExportScope = false;
bool withFunctionTypeParameters = false;
bool withImports = true;
bool withLibraryAugmentations = false;
bool withMacroStackTraces = false;
bool withMetadata = true;
bool withNonSynthetic = false;
bool withPropertyLinking = false;
bool withRedirectedConstructors = false;
bool withReturnType = true;
bool withSyntheticDartCoreImport = false;
ElementTextConfiguration({
this.filter = _filterTrue,
});
static bool _filterTrue(Object element) => true;
}
/// Writes the canonical text presentation of elements.
abstract class _AbstractElementWriter {
final TreeStringSink _sink;
final ElementPrinter _elementPrinter;
final ElementTextConfiguration configuration;
final _IdMap _idMap = _IdMap();
_AbstractElementWriter({
required TreeStringSink sink,
required ElementPrinter elementPrinter,
required this.configuration,
}) : _sink = sink,
_elementPrinter = elementPrinter;
ResolvedAstPrinter _createAstPrinter() {
return ResolvedAstPrinter(
sink: _sink,
elementPrinter: _elementPrinter,
configuration: ResolvedNodeTextConfiguration()
// TODO(scheglov): https://github.com/dart-lang/sdk/issues/49101
..withParameterElements = false,
withOffsets: true,
);
}
void _writeDirectiveUri(DirectiveUri uri) {
if (uri is DirectiveUriWithAugmentationImpl) {
_sink.write('${uri.augmentation.source.uri}');
} else if (uri is DirectiveUriWithLibraryImpl) {
_sink.write('${uri.library.source.uri}');
} else if (uri is DirectiveUriWithUnit) {
_sink.write('${uri.unit.source.uri}');
} else if (uri is DirectiveUriWithSource) {
_sink.write("source '${uri.source.uri}'");
} else if (uri is DirectiveUriWithRelativeUri) {
_sink.write("relativeUri '${uri.relativeUri}'");
} else if (uri is DirectiveUriWithRelativeUriString) {
_sink.write("relativeUriString '${uri.relativeUriString}'");
} else {
_sink.write('noRelativeUriString');
}
}
void _writeElements<T extends Object>(
String name,
List<T> elements,
void Function(T) write,
) {
var filtered = elements.where(configuration.filter).toList();
if (filtered.isNotEmpty) {
_sink.writelnWithIndent(name);
_sink.withIndent(() {
for (var element in filtered) {
write(element);
}
});
}
}
void _writeExportedReferences(LibraryElementImpl e) {
var exportedReferences = e.exportedReferences.toList();
exportedReferences.sortBy((e) => e.reference.toString());
for (var exported in exportedReferences) {
_sink.writeIndentedLine(() {
if (exported is ExportedReferenceDeclared) {
_sink.write('declared ');
} else if (exported is ExportedReferenceExported) {
_sink.write('exported${exported.locations} ');
}
_elementPrinter.writeReference(exported.reference);
});
}
}
void _writeFieldNameNonPromotabilityInfo(
Map<String, FieldNameNonPromotabilityInfo>? info,
) {
if (info == null || info.isEmpty) {
return;
}
_sink.writelnWithIndent('fieldNameNonPromotabilityInfo');
_sink.withIndent(() {
for (var entry in info.entries) {
_sink.writelnWithIndent(entry.key);
_sink.withIndent(() {
_elementPrinter.writeElementList(
'conflictingFields',
entry.value.conflictingFields,
);
_elementPrinter.writeElementList(
'conflictingGetters',
entry.value.conflictingGetters,
);
_elementPrinter.writeElementList(
'conflictingNsmClasses',
entry.value.conflictingNsmClasses,
);
});
}
});
}
void _writeNode(AstNode node) {
_sink.writeIndent();
node.accept(
_createAstPrinter(),
);
}
void _writeReference(ElementImpl e) {
if (e.reference case var reference?) {
_sink.writeIndentedLine(() {
_sink.write('reference: ');
_elementPrinter.writeReference(reference);
});
}
}
}
/// Writes the canonical text presentation of elements.
class _Element2Writer extends _AbstractElementWriter {
_Element2Writer({
required super.sink,
required super.elementPrinter,
required super.configuration,
});
void writeLibraryElement(LibraryElement2 e) {
expect(e.enclosingElement2, isNull);
_sink.writelnWithIndent('library');
_sink.withIndent(() {
_writeReference(e as ElementImpl);
var name = e.name;
if (name != null && name.isNotEmpty) {
_sink.writelnWithIndent('name: $name');
}
_writeDocumentation(e.documentationComment);
_writeMetadata(e.metadata);
_writeSinceSdkVersion(e.sinceSdkVersion);
// _writeElements(
// 'libraryExports',
// e.libraryExports,
// _writeLibraryExportElement,
// );
// TODO(brianwilkerson): Consider adding `fragments` as a convenience
// getter in `_Fragmented`
var fragments = <LibraryFragment>[];
for (LibraryFragment? fragment = e.firstFragment;
fragment != null;
fragment = fragment.nextFragment) {
fragments.add(fragment);
expect(fragment.element, same(e));
}
_writeElements('fragments', fragments, _writeLibraryFragment);
_writeElements('classes', e.classes, _writeInstanceElement);
_writeElements('enums', e.enums, _writeInstanceElement);
_writeElements('extensions', e.extensions, _writeInstanceElement);
_writeElements('extensionTypes', e.extensionTypes, _writeInstanceElement);
_writeElements('mixins', e.mixins, _writeInstanceElement);
_writeElements('topLevelVariables', e.topLevelVariables,
_writeTopLevelVariableElement);
_writeElements('getters', e.getters, _writeGetterElement);
_writeElements('setters', e.setters, _writeSetterElement);
if (configuration.withExportScope) {
_sink.writelnWithIndent('exportedReferences');
_sink.withIndent(() {
_writeExportedReferences(e as LibraryElementImpl);
});
_sink.writelnWithIndent('exportNamespace');
_sink.withIndent(() {
_writeExportNamespace(e);
});
}
_writeFieldNameNonPromotabilityInfo(
(e as LibraryElementImpl).fieldNameNonPromotabilityInfo);
_writeMacroDiagnostics(e);
});
}
void _assertNonSyntheticElementSelf(Element2 element) {
expect(element.isSynthetic, isFalse);
expect(element.nonSynthetic2, same(element));
}
String _elementName(Element2 e) {
var name = e.name ?? '<null>';
if (e is SetterElement) {
expect(name, endsWith('='));
}
if (name.isEmpty && e is ConstructorElement2) {
return 'new';
}
return name;
}
String _fragmentName(Fragment f) {
var name = f.name ?? '<null>';
if (f is PropertyAccessorElementImpl && f.isSetter) {
expect(name, endsWith('='));
}
if (name.isEmpty && f is ConstructorFragment) {
return 'new';
}
return name;
}
void _writeCodeRange(Element2 e) {
if (configuration.withCodeRanges && !e.isSynthetic) {
if (e is MaybeAugmentedInstanceElementMixin) {
e = e.declaration;
}
if (e is ElementImpl) {
_sink.writelnWithIndent('codeOffset: ${e.codeOffset}');
_sink.writelnWithIndent('codeLength: ${e.codeLength}');
} else {
throw UnsupportedError('Code range not supported for ${e.runtimeType}');
}
}
}
void _writeConstructorElement(ConstructorElement2 e) {
// Check that the reference exists, and filled with the element.
// var reference = e.reference;
// if (reference == null) {
// fail('Every constructor must have a reference.');
// }
_sink.writeIndentedLine(() {
_sink.writeIf(e.isSynthetic, 'synthetic ');
// _sink.writeIf(e.isExternal, 'external ');
_sink.writeIf(e.isConst, 'const ');
_sink.writeIf(e.isFactory, 'factory ');
expect(e.isAbstract, isFalse);
_writeElementName(e);
});
_sink.withIndent(() {
_writeElementReference(e);
// _writeEnclosingElement(e);
_writeDocumentation(e.documentationComment);
_writeMetadata(e.metadata);
_writeSinceSdkVersion(e.sinceSdkVersion);
// _writeDisplayName(e);
// _writeParameterElements(e.parameters2);
// _writeElements(
// 'constantInitializers',
// e.constantInitializers,
// _writeNode,
// );
var superConstructor = e.superConstructor2;
if (superConstructor != null) {
var enclosingElement = superConstructor.enclosingElement2;
if (enclosingElement is ClassElement2 &&
!enclosingElement.isDartCoreObject) {
_writeElementReference(superConstructor, label: 'superConstructor');
}
}
var redirectedConstructor = e.redirectedConstructor2;
if (redirectedConstructor != null) {
_writeElementReference(redirectedConstructor,
label: 'redirectedConstructor');
}
// _writeNonSyntheticElement(e);
_writeMacroDiagnostics(e);
_writeFragmentReference(e.firstFragment, label: 'firstFragment');
});
// if (e.isSynthetic) {
// expect(e.nameOffset, -1);
// expect(e.nonSynthetic, same(e.enclosingElement));
// } else {
// expect(e.nameOffset, isPositive);
// }
}
void _writeConstructorFragment(ConstructorFragment f) {
// Check that the reference exists, and filled with the element.
var reference = (f as ConstructorElementImpl).reference;
if (reference == null) {
fail('Every constructor must have a reference.');
}
_sink.writeIndentedLine(() {
_sink.writeIf(f.isAugmentation, 'augment ');
_sink.writeIf(f.isSynthetic, 'synthetic ');
_sink.writeIf(f.isExternal, 'external ');
_sink.writeIf(f.isConst, 'const ');
_sink.writeIf(f.isFactory, 'factory ');
expect(f.isAbstract, isFalse);
_writeFragmentName(f);
});
_sink.withIndent(() {
_writeFragmentReference(f);
_writeFragmentReference(f.enclosingFragment, label: 'enclosingFragment');
_writeDocumentation(f.documentationComment);
_writeMetadata(f.metadata);
_writeSinceSdkVersion(f.sinceSdkVersion);
_writeCodeRange(f);
// _writeDisplayName(f);
var periodOffset = f.periodOffset;
var nameEnd = f.nameEnd;
if (periodOffset != null && nameEnd != null) {
_sink.writelnWithIndent('periodOffset: $periodOffset');
_sink.writelnWithIndent('nameEnd: $nameEnd');
}
// _writeParameterElements(f.parameters);
_writeElements(
'constantInitializers',
f.constantInitializers,
_writeNode,
);
var superConstructor = f.superConstructor;
if (superConstructor != null) {
var enclosingElement = superConstructor.enclosingElement3;
if (enclosingElement is ClassElement &&
!enclosingElement.isDartCoreObject) {
_elementPrinter.writeNamedElement(
'superConstructor',
superConstructor,
);
}
}
var redirectedConstructor = f.redirectedConstructor;
if (redirectedConstructor != null) {
_elementPrinter.writeNamedElement(
'redirectedConstructor',
redirectedConstructor,
);
}
// _writeNonSyntheticElement(f);
_writeMacroDiagnostics(f);
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
});
expect(f.isAsynchronous, isFalse);
expect(f.isGenerator, isFalse);
if (f.isSynthetic) {
expect(f.nameOffset, -1);
expect(f.nonSynthetic, same(f.enclosingElement3));
} else {
expect(f.nameOffset, isPositive);
}
}
void _writeDocumentation(String? documentation) {
if (documentation != null) {
var str = documentation;
str = str.replaceAll('\n', r'\n');
str = str.replaceAll('\r', r'\r');
_sink.writelnWithIndent('documentationComment: $str');
}
}
void _writeElementName(Element2 e) {
_sink.write(_elementName(e));
}
void _writeElementReference(Element2? e, {String? label}) {
if (e == null) {
return;
}
if (e is MaybeAugmentedInstanceElementMixin) {
e = e.declaration;
}
if (e is ElementImpl) {
if (e.reference case var reference?) {
_sink.writeIndentedLine(() {
_sink.write(label ?? 'reference');
_sink.write(': ');
_elementPrinter.writeReference(reference);
});
}
// } else if (e is MethodElementImpl2) {
// if (e.reference case var reference?) {
// _sink.writeIndentedLine(() {
// _sink.write(label ?? 'reference: ');
// _elementPrinter.writeReference(reference);
// });
// }
} else {
_sink.writeIndentedLine(() {
_sink.write(label ?? 'reference');
_sink.write(': ');
_sink.write('<none>');
});
}
}
void _writeEnclosingElement(Element2 e) {
_elementPrinter.writeNamedElement(
'enclosingElement2',
e.enclosingElement2 as Element?,
);
}
void _writeExportNamespace(LibraryElement2 e) {
var map = e.exportNamespace.definedNames;
var sortedEntries = map.entries.sortedBy((entry) => entry.key);
for (var entry in sortedEntries) {
_elementPrinter.writeNamedElement(entry.key, entry.value);
}
}
void _writeFieldElement(FieldElement2 e) {
DartType type = e.type;
expect(type, isNotNull);
// if (e.isSynthetic) {
// expect(e.nameOffset, -1);
// } else {
// if (!e.isAugmentation) {
// expect(e.getter, isNotNull);
// }
// expect(e.nameOffset, isPositive);
// _assertNonSyntheticElementSelf(e);
// }
_sink.writeIndentedLine(() {
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e is FieldElementImpl && e.isAbstract, 'abstract ');
_sink.writeIf(e is FieldElementImpl && e.isCovariant, 'covariant ');
_sink.writeIf(e is FieldElementImpl && e.isExternal, 'external ');
_sink.writeIf(e.isLate, 'late ');
_sink.writeIf(e.isFinal, 'final ');
_sink.writeIf(e.isConst, 'const ');
if (e is FieldElementImpl) {
_sink.writeIf(e.isEnumConstant, 'enumConstant ');
_sink.writeIf(e.isPromotable, 'promotable ');
}
_writeElementName(e);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[e]}');
// var getter = e.getter;
// if (getter != null) {
// _sink.writelnWithIndent('getter: ${_idMap[getter]}');
// }
// var setter = e.setter;
// if (setter != null) {
// _sink.writelnWithIndent('setter: ${_idMap[setter]}');
// }
// }
// }
_sink.withIndent(() {
_writeElementReference(e);
_writeElementReference(e.enclosingElement2!, label: 'enclosingElement');
// _writeDocumentation(e.documentationComment);
// _writeMetadata(e.metadata);
// _writeSinceSdkVersion(e.sinceSdkVersion);
// _writeCodeRange(e);
// _writeTypeInferenceError(e);
_writeType('type', e.type);
// _writeShouldUseTypeForInitializerInference(e);
// _writeConstantInitializer(e);
// _writeNonSyntheticElement(e);
// writeLinking();
_writeMacroDiagnostics(e);
_writeFragmentReference(e.firstFragment, label: 'firstFragment');
_writeElementReference(e.getter, label: 'getter');
_writeElementReference(e.setter, label: 'setter');
});
}
void _writeFieldFragment(FieldFragment f) {
// TODO(brianwilkerson): Implement `type`.
// DartType type = e.type;
// expect(type, isNotNull);
// if (f.isSynthetic) {
// expect(f.nameOffset, -1);
// } else {
// // TODO(brianwilkerson): Implement `isAugmentation`.
// if (!f.isAugmentation) {
// expect(f.getter2, isNotNull);
// }
// expect(f.nameOffset, isPositive);
// // _assertNonSyntheticElementSelf(e);
// }
_sink.writeIndentedLine(() {
// _sink.writeIf(f.isAugmentation, 'augment ');
// _sink.writeIf(f.isSynthetic, 'synthetic ');
// _sink.writeIf(f.isStatic, 'static ');
_sink.writeIf(f is FieldElementImpl && f.isAbstract, 'abstract ');
_sink.writeIf(f is FieldElementImpl && f.isCovariant, 'covariant ');
_sink.writeIf(f is FieldElementImpl && f.isExternal, 'external ');
// _sink.writeIf(f.isLate, 'late ');
// _sink.writeIf(f.isFinal, 'final ');
// _sink.writeIf(f.isConst, 'const ');
if (f is FieldElementImpl) {
_sink.writeIf(f.isEnumConstant, 'enumConstant ');
_sink.writeIf(f.isPromotable, 'promotable ');
}
_writeFragmentName(f);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[f]}');
// var getter = f.getter2;
// if (getter != null) {
// _sink.writelnWithIndent('getter: ${_idMap[getter]}');
// }
// var setter = f.setter2;
// if (setter != null) {
// _sink.writelnWithIndent('setter: ${_idMap[setter]}');
// }
// }
// }
_sink.withIndent(() {
_writeFragmentReference(f);
_writeFragmentReference(f.enclosingFragment, label: 'enclosingFragment');
// _writeDocumentation(f.documentationComment);
// _writeMetadata(f.metadata);
// _writeSinceSdkVersion(f.sinceSdkVersion);
// _writeCodeRange(f);
// _writeTypeInferenceError(f);
// _writeType('type', f.type);
// _writeShouldUseTypeForInitializerInference(f);
// _writeConstantInitializer(f);
// _writeNonSyntheticElement(f);
// writeLinking();
// _writeMacroDiagnostics(f);
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
_writeFragmentReference(f.getter2, label: 'getter2');
_writeFragmentReference(f.setter2, label: 'setter2');
});
}
void _writeFragentBodyModifiers(ExecutableFragment f) {
if (f.isAsynchronous) {
expect(f.isSynchronous, isFalse);
_sink.write(' async');
}
if (f.isSynchronous && f.isGenerator) {
expect(f.isAsynchronous, isFalse);
_sink.write(' sync');
}
_sink.writeIf(f.isGenerator, '*');
if (f is ExecutableElementImpl && f.invokesSuperSelf) {
_sink.write(' invokesSuperSelf');
}
}
void _writeFragmentCodeRange(Fragment f) {
if (configuration.withCodeRanges) {
if (f is ElementImpl) {
var e = f as ElementImpl;
if (!e.isSynthetic) {
_sink.writelnWithIndent('codeOffset: ${e.codeOffset}');
_sink.writelnWithIndent('codeLength: ${e.codeLength}');
}
}
}
}
void _writeFragmentName(Fragment f) {
var name = _fragmentName(f);
_sink.write(name);
var offset = f.nameOffset;
if (offset != null) {
_sink.write(name.isNotEmpty ? ' @' : '@');
_sink.write(offset);
}
}
void _writeFragmentReference(Fragment? f, {String? label}) {
if (f == null) {
return;
}
if (f is CompilationUnitElementImpl) {
_sink.writeIndentedLine(() {
_sink.write(label ?? 'reference');
_sink.write(': ');
_elementPrinter.writeReference(f.reference!);
});
return;
}
Element2? element;
if (f is ElementImpl) {
element = f as ElementImpl;
} else {
element = f.element;
if (element is! ElementImpl) {
if (element is NotAugmentedInstanceElementImpl) {
element = element.baseElement;
} else if (element is MaybeAugmentedInstanceElementMixin) {
element = element.declaration;
}
}
}
if (element is! ElementImpl) {
_sink.writeIndentedLine(() {
_sink.write(label ?? 'reference');
_sink.write(': <none>');
});
return;
}
if (element.reference case var reference?) {
_sink.writeIndentedLine(() {
_sink.write(label ?? 'reference');
_sink.write(': ');
_elementPrinter.writeReference(reference);
});
}
}
// void _writeTypeParameterElement(TypeParameterElement2 e) {
// e as TypeParameterElementImpl;
// _sink.writeIndentedLine(() {
// _sink.write('${(e as TypeParameterElementImpl).variance.name} ');
// _writeElementName(e);
// });
// _sink.withIndent(() {
// _writeCodeRange(e);
// var bound = e.bound;
// if (bound != null) {
// _writeType('bound', bound);
// }
// // var defaultType = e.defaultType;
// // if (defaultType != null) {
// // _writeType('defaultType', defaultType);
// // }
// _writeMetadata(e.metadata);
// });
// _assertNonSyntheticElementSelf(e);
// }
void _writeGetterElement(GetterElement e) {
var variable = e.variable3;
if (variable != null) {
var variableEnclosing = variable.enclosingElement2;
if (variableEnclosing is LibraryElement2) {
expect(variableEnclosing.topLevelVariables, contains(variable));
} else if (variableEnclosing is InterfaceElement2) {
expect(variableEnclosing.fields2, contains(variable));
}
}
// if (e.isSynthetic) {
// expect(e.nameOffset, -1);
// } else {
// expect(e.nameOffset, isPositive);
// _assertNonSyntheticElementSelf(e);
// }
_sink.writeIndentedLine(() {
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e.isAbstract, 'abstract ');
_sink.writeIf(e.isExternal, 'external ');
_sink.write('get ');
_writeElementName(e);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[e]}');
// if (e.variable2 case var variable?) {
// _sink.writelnWithIndent('variable: ${_idMap[variable]}');
// } else {
// _sink.writelnWithIndent('variable: <null>');
// }
// }
// }
_sink.withIndent(() {
_writeElementReference(e);
_writeElementReference(e.enclosingElement2, label: 'enclosingElement');
_writeDocumentation(e.documentationComment);
_writeMetadata(e.metadata);
_writeSinceSdkVersion(e.sinceSdkVersion);
expect(e.typeParameters2, isEmpty);
// _writeParameterElements(e.parameters2);
// _writeReturnType(e.returnType);
// _writeNonSyntheticElement(e);
// writeLinking();
_writeMacroDiagnostics(e);
_writeFragmentReference(e.firstFragment, label: 'firstFragment');
});
}
void _writeGetterFragment(GetterFragment f) {
var variable = f.variable3;
if (variable != null) {
var variableEnclosing = variable.enclosingFragment;
if (variableEnclosing is LibraryFragment) {
expect(variableEnclosing.topLevelVariables2, contains(variable));
} else if (variableEnclosing is InterfaceFragment) {
expect(variableEnclosing.fields2, contains(variable));
}
} else {
expect(f.isAugmentation, isTrue);
expect(f.previousFragment, isNull);
}
// if (f.isSynthetic) {
// expect(f.nameOffset, -1);
// } else {
// expect(f.nameOffset, isPositive);
// _assertNonSyntheticElementSelf(f);
// }
_sink.writeIndentedLine(() {
_sink.writeIf(f.isAugmentation, 'augment ');
// _sink.writeIf(e.isSynthetic, 'synthetic ');
// _sink.writeIf(e.isStatic, 'static ');
// _sink.writeIf(e.isAbstract, 'abstract ');
// _sink.writeIf(e.isExternal, 'external ');
_sink.write('get ');
_writeFragmentName(f);
// _writeBodyModifiers(e);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[e]}');
// if (e.variable2 case var variable?) {
// _sink.writelnWithIndent('variable: ${_idMap[variable]}');
// } else {
// _sink.writelnWithIndent('variable: <null>');
// }
// }
// }
_sink.withIndent(() {
_writeFragmentReference(f);
_writeFragmentReference(f.enclosingFragment, label: 'enclosingFragment');
_writeDocumentation(f.documentationComment);
_writeMetadata(f.metadata);
_writeSinceSdkVersion(f.sinceSdkVersion);
// _writeCodeRange(f);
// expect(f.typeParameters2, isEmpty);
// _writeParameterElements(f.parameters2);
// _writeReturnType(f.returnType);
// _writeNonSyntheticElement(f);
// writeLinking();
// _writeMacroDiagnostics(f);
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
});
}
void _writeInstanceElement(InstanceElement2 e) {
_sink.writeIndentedLine(() {
switch (e) {
case ClassElement2():
_sink.writeIf(e.isAbstract, 'abstract ');
// _sink.writeIf(e.isMacro, 'macro ');
_sink.writeIf(e.isSealed, 'sealed ');
_sink.writeIf(e.isBase, 'base ');
_sink.writeIf(e.isInterface, 'interface ');
_sink.writeIf(e.isFinal, 'final ');
// _writeNotSimplyBounded(e);
_sink.writeIf(e.isMixinClass, 'mixin ');
_sink.write('class ');
_sink.writeIf(e.isMixinApplication, 'alias ');
case EnumElement2():
// _writeNotSimplyBounded(e);
_sink.write('enum ');
case ExtensionElement2():
_sink.write('extension ');
case ExtensionTypeElement2():
// _sink.writeIf(
// e.hasRepresentationSelfReference,
// 'hasRepresentationSelfReference ',
// );
// _sink.writeIf(
// e.hasImplementsSelfReference,
// 'hasImplementsSelfReference ',
// );
// // _writeNotSimplyBounded(e);
_sink.write('extension type ');
case MixinElement2():
_sink.writeIf(e.isBase, 'base ');
// _writeNotSimplyBounded(e);
_sink.write('mixin ');
}
_writeElementName(e);
});
_sink.withIndent(() {
_writeElementReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e.documentationComment);
// _writeMetadata(e.metadata);
_writeSinceSdkVersion(e.sinceSdkVersion);
_writeCodeRange(e);
// _writeElements('typeParameters', e.typeParameters2, _writeTypeParameterElement);
_writeMacroDiagnostics(e);
_writeFragmentReference(e.firstFragment, label: 'firstFragment');
if (e is InterfaceElement2) {
var supertype = e.supertype;
if (supertype != null &&
(supertype.element.name != 'Object' || e.mixins.isNotEmpty)) {
_writeType('supertype', supertype);
}
}
if (e is ExtensionTypeElement2) {
// _elementPrinter.writeNamedElement('representation', e.representation2);
// _elementPrinter.writeNamedElement(
// 'primaryConstructor', e.primaryConstructor2);
_elementPrinter.writeNamedType('typeErasure', e.typeErasure);
}
if (e is MixinElement2) {
_elementPrinter.writeTypeList(
'superclassConstraints',
e.superclassConstraints,
);
}
// TODO(brianwilkerson): Add a `writeTypeList2` that will use the new API
// version of the elements of type parameters.
// _elementPrinter.writeTypeList('mixins', e.mixins);
// _elementPrinter.writeTypeList('interfaces', e.interfaces);
if (configuration.withAllSupertypes && e is InterfaceElement2) {
var sorted = e.allSupertypes.sortedBy((t) => t.element.name);
_elementPrinter.writeTypeList('allSupertypes', sorted);
}
_writeElements('fields', e.fields2, _writeFieldElement);
if (e is InterfaceElement2) {
var constructors = e.constructors2;
if (e is MixinElement2) {
expect(constructors, isEmpty);
} else if (configuration.withConstructors) {
_writeElements(
'constructors', constructors, _writeConstructorElement);
}
}
_writeElements('getters', e.getters2, _writeGetterElement);
_writeElements('setters', e.setters2, _writeSetterElement);
_writeElements('methods', e.methods2, _writeMethodElement);
});
_assertNonSyntheticElementSelf(e);
}
void _writeInstanceFragment(InstanceFragment f) {
_sink.writeIndentedLine(() {
switch (f) {
case ClassFragment():
// TODO(brianwilkerson): Figure out why we can't ask the fragments
// these questions.
// _sink.writeIf(f.isAbstract, 'abstract ');
// _sink.writeIf(f.isMacro, 'macro ');
// _sink.writeIf(f.isSealed, 'sealed ');
// _sink.writeIf(f.isBase, 'base ');
// _sink.writeIf(f.isInterface, 'interface ');
// _sink.writeIf(f.isFinal, 'final ');
// _writeNotSimplyBounded(f);
// _sink.writeIf(f.isMixinClass, 'mixin ');
_sink.write('class ');
// _sink.writeIf(f.isMixinApplication, 'alias ');
case EnumFragment():
// _writeNotSimplyBounded(f);
_sink.write('enum ');
case ExtensionFragment():
_sink.write('extension ');
case ExtensionTypeFragment():
// _sink.writeIf(
// e.hasRepresentationSelfReference,
// 'hasRepresentationSelfReference ',
// );
// _sink.writeIf(
// e.hasImplementsSelfReference,
// 'hasImplementsSelfReference ',
// );
// // _writeNotSimplyBounded(e);
_sink.write('extension type ');
case MixinFragment():
// _sink.writeIf(f.isBase, 'base ');
// _writeNotSimplyBounded(f);
_sink.write('mixin ');
}
var name = f.element.name;
if (name != null) {
_sink.write(name);
}
var offset = f.nameOffset;
if (offset != null) {
_sink.write(' @');
_sink.write(offset);
}
});
_sink.withIndent(() {
_writeFragmentReference(f);
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
_writeElements('fields', f.fields2, _writeFieldFragment);
if (f is InterfaceFragment) {
var constructors = f.constructors2;
if (f is MixinElement2) {
expect(constructors, isEmpty);
} else if (configuration.withConstructors) {
_writeElements(
'constructors', constructors, _writeConstructorFragment);
}
}
_writeElements('getters', f.getters, _writeGetterFragment);
_writeElements('setters', f.setters, _writeSetterFragment);
_writeElements('methods', f.methods2, _writeMethodFragment);
});
}
void _writeLibraryFragment(LibraryFragment f) {
var reference = (f as CompilationUnitElementImpl).reference!;
_sink.writeIndentedLine(() {
_elementPrinter.writeReference(reference);
});
_sink.withIndent(() {
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
_writeMetadata(f.metadata);
if (configuration.withImports) {
var imports = f.libraryImports2.where((import) {
return configuration.withSyntheticDartCoreImport ||
!import.isSynthetic;
}).toList();
_writeElements(
'libraryImports',
imports,
_writeLibraryImport,
);
}
_writeElements('prefixes', f.prefixes, _writePrefixElement);
// _writeElements(
// 'libraryExports', f.libraryExports, _writeLibraryExportElement);
// _writeElements('parts', f.parts, _writePartElement);
_writeElements('classes', f.classes2, _writeInstanceFragment);
_writeElements('enums', f.enums2, _writeInstanceFragment);
_writeElements('extensions', f.extensions2, _writeInstanceFragment);
_writeElements(
'extensionTypes',
f.extensionTypes2,
_writeInstanceFragment,
);
_writeElements('mixins', f.mixins2, _writeInstanceFragment);
// _writeElements('typeAliases', f.typeAliases, _writeTypeAliasElement);
_writeElements(
'topLevelVariables',
f.topLevelVariables2,
_writeTopLevelVariableFragment,
);
_writeElements(
'getters',
f.getters,
_writeGetterFragment,
);
_writeElements(
'setters',
f.setters,
_writeSetterFragment,
);
// _writeElements('functions', f.functions, _writeFunctionElement);
});
}
void _writeLibraryImport(LibraryImport e) {
(e as LibraryImportElementImpl).location;
_sink.writeIndentedLine(() {
_writeDirectiveUri(e.uri);
_sink.writeIf(e.isSynthetic, ' synthetic');
// _writeImportElementPrefix(e.prefix);
});
_sink.withIndent(() {
_writeElementReference(e);
// _writeEnclosingElement(e);
_writeMetadata(e.metadata);
// _writeNamespaceCombinators(e.combinators);
});
}
void _writeMacroDiagnostics(Element2 e) {
void writeTypeAnnotationLocation(TypeAnnotationLocation location) {
switch (location) {
case AliasedTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('AliasedTypeLocation');
case ElementTypeLocation():
_sink.writelnWithIndent('ElementTypeLocation');
_sink.withIndent(() {
_elementPrinter.writeNamedElement('element', location.element);
});
case ExtendsClauseTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('ExtendsClauseTypeLocation');
case FormalParameterTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('FormalParameterTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case ListIndexTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('ListIndexTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case RecordNamedFieldTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('RecordNamedFieldTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case RecordPositionalFieldTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('RecordPositionalFieldTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case ReturnTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('ReturnTypeLocation');
case VariableTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('VariableTypeLocation');
default:
// TODO(scheglov): Handle this case.
throw UnimplementedError('${location.runtimeType}');
}
}
/// Returns `true` if patterns were printed.
/// Returns `false` if no patterns configured.
bool printMessagePatterns(String message) {
var patterns = configuration.macroDiagnosticMessagePatterns;
if (patterns == null) {
return false;
}
_sink.writelnWithIndent('contains');
_sink.withIndent(() {
for (var pattern in patterns) {
if (message.contains(pattern)) {
_sink.writelnWithIndent(pattern);
}
}
});
return true;
}
void writeMessage(MacroDiagnosticMessage object) {
// Write the message.
if (!printMessagePatterns(object.message)) {
var message = object.message;
const stackTraceText = '#0';
var stackTraceIndex = message.indexOf(stackTraceText);
if (stackTraceIndex >= 0) {
var end = stackTraceIndex + stackTraceText.length;
var withoutStackTrace = message.substring(0, end);
if (configuration.withMacroStackTraces) {
_sink.writelnWithIndent('message:\n$message');
} else {
_sink.writelnWithIndent('message:\n$withoutStackTrace <cut>');
}
} else {
_sink.writelnWithIndent('message: $message');
}
}
// Write the target.
var target = object.target;
switch (target) {
case ApplicationMacroDiagnosticTarget():
_sink.writelnWithIndent('target: ApplicationMacroDiagnosticTarget');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${target.annotationIndex}',
);
});
case ElementMacroDiagnosticTarget():
_sink.writelnWithIndent('target: ElementMacroDiagnosticTarget');
_sink.withIndent(() {
_elementPrinter.writeNamedElement('element', target.element);
});
case ElementAnnotationMacroDiagnosticTarget():
_sink.writelnWithIndent(
'target: ElementAnnotationMacroDiagnosticTarget',
);
_sink.withIndent(() {
_elementPrinter.writeNamedElement('element', target.element);
_sink.writelnWithIndent(
'annotationIndex: ${target.annotationIndex}',
);
});
case TypeAnnotationMacroDiagnosticTarget():
_sink.writelnWithIndent(
'target: TypeAnnotationMacroDiagnosticTarget',
);
_sink.withIndent(() {
writeTypeAnnotationLocation(target.location);
});
}
}
if (e case MacroTargetElement macroTarget) {
_sink.writeElements(
'macroDiagnostics',
macroTarget.macroDiagnostics,
(diagnostic) {
switch (diagnostic) {
case ArgumentMacroDiagnostic():
_sink.writelnWithIndent('ArgumentMacroDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_sink.writelnWithIndent(
'argumentIndex: ${diagnostic.argumentIndex}',
);
_sink.writelnWithIndent('message: ${diagnostic.message}');
});
case DeclarationsIntrospectionCycleDiagnostic():
_sink.writelnWithIndent(
'DeclarationsIntrospectionCycleDiagnostic',
);
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_elementPrinter.writeNamedElement(
'introspectedElement',
diagnostic.introspectedElement,
);
_sink.writeElements(
'components',
diagnostic.components,
(component) {
_sink.writelnWithIndent(
'DeclarationsIntrospectionCycleComponent',
);
_sink.withIndent(() {
_elementPrinter.writeNamedElement(
'element',
component.element,
);
_sink.writelnWithIndent(
'annotationIndex: ${component.annotationIndex}',
);
_elementPrinter.writeNamedElement(
'introspectedElement',
component.introspectedElement,
);
});
},
);
});
case ExceptionMacroDiagnostic():
_sink.writelnWithIndent('ExceptionMacroDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
if (!printMessagePatterns(diagnostic.message)) {
_sink.writelnWithIndent(
'message: ${diagnostic.message}',
);
}
if (configuration.withMacroStackTraces) {
_sink.writelnWithIndent(
'stackTrace:\n${diagnostic.stackTrace}',
);
}
});
case InvalidMacroTargetDiagnostic():
_sink.writelnWithIndent('InvalidMacroTargetDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_sink.writeElements(
'supportedKinds',
diagnostic.supportedKinds,
(kindName) {
_sink.writelnWithIndent(kindName);
},
);
});
case MacroDiagnostic():
_sink.writelnWithIndent('MacroDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent('message: MacroDiagnosticMessage');
_sink.withIndent(() {
writeMessage(diagnostic.message);
});
_sink.writeElements(
'contextMessages',
diagnostic.contextMessages,
(message) {
_sink.writelnWithIndent('MacroDiagnosticMessage');
_sink.withIndent(() {
writeMessage(message);
});
},
);
_sink.writelnWithIndent(
'severity: ${diagnostic.severity.name}',
);
if (diagnostic.correctionMessage case var correctionMessage?) {
_sink.writelnWithIndent(
'correctionMessage: $correctionMessage',
);
}
});
case NotAllowedDeclarationDiagnostic():
_sink.writelnWithIndent('NotAllowedDeclarationDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_sink.writelnWithIndent(
'phase: ${diagnostic.phase.name}',
);
var nodeRangesStr = diagnostic.nodeRanges
.map((r) => '(${r.offset}, ${r.length})')
.join(' ');
_sink.writelnWithIndent('nodeRanges: $nodeRangesStr');
_sink.writeln('---');
_sink.write(diagnostic.code);
_sink.writeln('---');
});
}
},
);
}
}
void _writeMetadata(List<ElementAnnotation> annotations) {
if (configuration.withMetadata) {
if (annotations.isNotEmpty) {
_sink.writelnWithIndent('metadata');
_sink.withIndent(() {
for (var annotation in annotations) {
annotation as ElementAnnotationImpl;
_writeNode(annotation.annotationAst);
}
});
}
}
}
void _writeMethodElement(MethodElement2 e) {
_sink.writeIndentedLine(() {
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e.isAbstract, 'abstract ');
// _sink.writeIf(e.isExternal, 'external ');
_writeElementName(e);
});
_sink.withIndent(() {
_writeElementReference(e);
// _writeElementReference(e.enclosingElement2, label: 'enclosingElement2');
_writeDocumentation(e.documentationComment);
_writeMetadata(e.metadata);
_writeSinceSdkVersion(e.sinceSdkVersion);
// _writeTypeInferenceError(e);
// _writeTypeParameterElements(e.typeParameters2);
// _writeParameterElements(e.parameters2);
// _writeReturnType(e.returnType);
// _writeNonSyntheticElement(e);
_writeMacroDiagnostics(e);
_writeFragmentReference(e.firstFragment, label: 'firstFragment');
});
// if (e.isSynthetic && e.enclosingElement2 is EnumElementImpl) {
// expect(e.name, 'toString');
// expect(e.nonSynthetic2, same(e.enclosingElement2));
// } else {
// _assertNonSyntheticElementSelf(e);
// }
}
void _writeMethodFragment(MethodFragment f) {
_sink.writeIndentedLine(() {
_sink.writeIf(f.isAugmentation, 'augment ');
// _sink.writeIf(f.isSynthetic, 'synthetic ');
// _sink.writeIf(f.isStatic, 'static ');
// _sink.writeIf(f.isAbstract, 'abstract ');
// _sink.writeIf(f.isExternal, 'external ');
_writeFragmentName(f);
_writeFragentBodyModifiers(f);
});
_sink.withIndent(() {
_writeFragmentReference(f);
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
_writeFragmentReference(f.enclosingFragment, label: 'enclosingFragment');
_writeDocumentation(f.documentationComment);
_writeMetadata(f.metadata);
_writeSinceSdkVersion(f.sinceSdkVersion);
_writeFragmentCodeRange(f);
// _writeTypeInferenceError(f);
// _writeTypeParameterElements(f.typeParameters);
// _writeParameterElements(f.parameters);
// _writeReturnType(f.returnType);
// _writeNonSyntheticElement(f);
// _writeMacroDiagnostics(f);
// _writeAugmentationTarget(f);
// _writeAugmentation(f);
});
}
void _writePrefixElement(PrefixElement2 e) {
_sink.writeIndentedLine(() {
_writeElementName(e);
});
_sink.withIndent(() {
_writeElementReference(e);
// _writeEnclosingElement(e);
});
}
void _writeSetterElement(SetterElement e) {
var variable = e.variable3;
if (variable != null) {
var variableEnclosing = variable.enclosingElement2;
if (variableEnclosing is LibraryElement2) {
expect(variableEnclosing.topLevelVariables, contains(variable));
} else if (variableEnclosing is InterfaceElement2) {
expect(variableEnclosing.fields2, contains(variable));
}
}
// if (e.isSynthetic) {
// expect(e.nameOffset, -1);
// } else {
// expect(e.nameOffset, isPositive);
// _assertNonSyntheticElementSelf(e);
// }
_sink.writeIndentedLine(() {
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e.isAbstract, 'abstract ');
_sink.writeIf(e.isExternal, 'external ');
_sink.write('set ');
_writeElementName(e);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[e]}');
// if (e.variable2 case var variable?) {
// _sink.writelnWithIndent('variable: ${_idMap[variable]}');
// } else {
// _sink.writelnWithIndent('variable: <null>');
// }
// }
// }
_sink.withIndent(() {
_writeElementReference(e);
_writeElementReference(e.enclosingElement2, label: 'enclosingElement');
_writeDocumentation(e.documentationComment);
_writeMetadata(e.metadata);
_writeSinceSdkVersion(e.sinceSdkVersion);
expect(e.typeParameters2, isEmpty);
// _writeParameterElements(e.parameters2);
// _writeReturnType(e.returnType);
// _writeNonSyntheticElement(e);
// writeLinking();
_writeMacroDiagnostics(e);
_writeFragmentReference(e.firstFragment, label: 'firstFragment');
});
}
void _writeSetterFragment(SetterFragment f) {
var variable = f.variable3;
if (variable != null) {
var variableEnclosing = variable.enclosingFragment;
if (variableEnclosing is LibraryFragment) {
expect(variableEnclosing.topLevelVariables2, contains(variable));
} else if (variableEnclosing is InterfaceFragment) {
expect(variableEnclosing.fields2, contains(variable));
}
} else {
expect(f.isAugmentation, isTrue);
expect(f.previousFragment, isNull);
}
// if (f.isSynthetic) {
// expect(f.nameOffset, -1);
// } else {
// expect(f.nameOffset, isPositive);
// _assertNonSyntheticElementSelf(f);
// }
_sink.writeIndentedLine(() {
_sink.writeIf(f.isAugmentation, 'augment ');
// _sink.writeIf(f.isSynthetic, 'synthetic ');
// _sink.writeIf(f.isStatic, 'static ');
// _sink.writeIf(f.isAbstract, 'abstract ');
// _sink.writeIf(f.isExternal, 'external ');
_sink.write('set ');
_writeFragmentName(f);
// _writeBodyModifiers(f);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[e]}');
// if (e.variable2 case var variable?) {
// _sink.writelnWithIndent('variable: ${_idMap[variable]}');
// } else {
// _sink.writelnWithIndent('variable: <null>');
// }
// }
// }
_sink.withIndent(() {
_writeFragmentReference(f);
_writeFragmentReference(f.enclosingFragment, label: 'enclosingFragment');
_writeDocumentation(f.documentationComment);
_writeMetadata(f.metadata);
_writeSinceSdkVersion(f.sinceSdkVersion);
// _writeCodeRange(f);
// expect(f.typeParameters2, isEmpty);
// _writeParameterElements(f.parameters2);
// _writeReturnType(f.returnType);
// _writeNonSyntheticElement(f);
// writeLinking();
// _writeMacroDiagnostics(f);
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
});
}
void _writeSinceSdkVersion(Version? version) {
if (version != null) {
_sink.writelnWithIndent('sinceSdkVersion: $version');
}
}
void _writeTopLevelVariableElement(TopLevelVariableElement2 e) {
DartType type = e.type;
expect(type, isNotNull);
if (!e.isSynthetic) {
expect(e.getter, isNotNull);
_assertNonSyntheticElementSelf(e);
}
_sink.writeIndentedLine(() {
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isLate, 'late ');
_sink.writeIf(e.isFinal, 'final ');
_sink.writeIf(e.isConst, 'const ');
_writeElementName(e);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[e]}');
// var getter = e.getter;
// if (getter != null) {
// _sink.writelnWithIndent('getter: ${_idMap[getter]}');
// }
// var setter = e.setter;
// if (setter != null) {
// _sink.writelnWithIndent('setter: ${_idMap[setter]}');
// }
// }
// }
_sink.withIndent(() {
_writeElementReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e.documentationComment);
_writeMetadata(e.metadata);
_writeSinceSdkVersion(e.sinceSdkVersion);
// _writeTypeInferenceError(e);
_writeType('type', e.type);
// _writeShouldUseTypeForInitializerInference(e);
// _writeConstantInitializer(e);
// _writeNonSyntheticElement(e);
// writeLinking();
_writeMacroDiagnostics(e);
_writeFragmentReference(e.firstFragment, label: 'firstFragment');
_writeElementReference(e.getter, label: 'getter');
_writeElementReference(e.setter, label: 'setter');
});
}
void _writeTopLevelVariableFragment(TopLevelVariableFragment f) {
// DartType type = f.type;
// expect(type, isNotNull);
// if (f.isSynthetic) {
// expect(f.nameOffset, -1);
// } else {
// if (!f.isAugmentation) {
// expect(f.getter, isNotNull);
// }
// expect(f.nameOffset, isPositive);
// _assertNonSyntheticElementSelf(f);
// }
_sink.writeIndentedLine(() {
_sink.writeIf(f.isAugmentation, 'augment ');
_sink.writeIf(f.isSynthetic, 'synthetic ');
// _sink.writeIf(f.isLate, 'late ');
_sink.writeIf(f.isFinal, 'final ');
_sink.writeIf(f.isConst, 'const ');
_writeFragmentName(f);
});
// void writeLinking() {
// if (configuration.withPropertyLinking) {
// _sink.writelnWithIndent('id: ${_idMap[e]}');
// var getter = e.getter;
// if (getter != null) {
// _sink.writelnWithIndent('getter: ${_idMap[getter]}');
// }
// var setter = e.setter;
// if (setter != null) {
// _sink.writelnWithIndent('setter: ${_idMap[setter]}');
// }
// }
// }
_sink.withIndent(() {
_writeFragmentReference(f);
_writeFragmentReference(f.enclosingFragment, label: 'enclosingFragment');
_writeDocumentation(f.documentationComment);
_writeMetadata(f.metadata);
_writeSinceSdkVersion(f.sinceSdkVersion);
// _writeCodeRange(f);
// _writeTypeInferenceError(f);
// _writeType('type', f.type);
// _writeShouldUseTypeForInitializerInference(f);
// _writeConstantInitializer(f);
// _writeNonSyntheticElement(f);
// writeLinking();
// _writeMacroDiagnostics(f);
_writeFragmentReference(f.previousFragment, label: 'previousFragment');
_writeFragmentReference(f.nextFragment, label: 'nextFragment');
_writeFragmentReference(f.getter2, label: 'getter2');
_writeFragmentReference(f.setter2, label: 'setter2');
});
}
void _writeType(String name, DartType type) {
_elementPrinter.writeNamedType(name, type);
// if (configuration.withFunctionTypeParameters) {
// if (type is FunctionType) {
// _sink.withIndent(() {
// // TODO(brianwilkerson): We need to define `parameters2` to return
// // `List<ParmaeterElement2>`.
// _writeParameterElements(type.parameters);
// });
// }
// }
}
}
/// Writes the canonical text presentation of elements.
class _ElementWriter extends _AbstractElementWriter {
_ElementWriter({
required super.sink,
required super.elementPrinter,
required super.configuration,
});
void writeLibraryElement(LibraryElementImpl e) {
expect(e.enclosingElement3, isNull);
_sink.writelnWithIndent('library');
_sink.withIndent(() {
var name = e.name;
if (name.isNotEmpty) {
_sink.writelnWithIndent('name: $name');
}
var nameOffset = e.nameOffset;
if (nameOffset != -1) {
_sink.writelnWithIndent('nameOffset: $nameOffset');
}
_writeLibraryOrAugmentationElement(e);
for (var part in e.parts) {
if (part.uri case DirectiveUriWithUnitImpl uri) {
expect(uri.unit.libraryOrAugmentationElement, same(e));
}
}
_writeElements('parts', e.parts, (part) {
_sink.writelnWithIndent(_idMap[part]);
});
_writeElements('units', e.units, (unit) {
_sink.writeIndent();
_elementPrinter.writeElement(unit);
_sink.withIndent(() {
_writeUnitElement(unit);
});
});
// All fragments have this library.
for (var unit in e.units) {
expect(unit.library, same(e));
}
if (configuration.withExportScope) {
_sink.writelnWithIndent('exportedReferences');
_sink.withIndent(() {
_writeExportedReferences(e);
});
_sink.writelnWithIndent('exportNamespace');
_sink.withIndent(() {
_writeExportNamespace(e);
});
}
_writeFieldNameNonPromotabilityInfo(e.fieldNameNonPromotabilityInfo);
_writeMacroDiagnostics(e);
});
}
void _assertNonSyntheticElementSelf(Element element) {
expect(element.isSynthetic, isFalse);
expect(element.nonSynthetic, same(element));
}
void _validateAugmentedInstanceElement(InstanceElementImpl e) {
InstanceElementImpl? current = e;
while (current != null) {
expect(current.augmented, same(e.augmented));
expect(current.thisType, same(e.thisType));
switch (e) {
case ExtensionElementImpl():
current as ExtensionElementImpl;
expect(current.extendedType, same(e.extendedType));
case ExtensionTypeElementImpl():
current as ExtensionTypeElementImpl;
expect(current.primaryConstructor, same(e.primaryConstructor));
expect(current.representation, same(e.representation));
expect(current.typeErasure, same(e.typeErasure));
}
current = current.augmentationTarget;
}
}
void _writeAugmentation(ElementImpl e) {
if (e case AugmentableElement(:var augmentation?)) {
_elementPrinter.writeNamedElement('augmentation', augmentation);
}
}
void _writeAugmentationElement(LibraryAugmentationElementImpl e) {
_writeLibraryOrAugmentationElement(e);
}
void _writeAugmentationImportElement(AugmentationImportElementImpl e) {
var uri = e.uri;
_sink.writeIndentedLine(() {
_writeDirectiveUri(e.uri);
});
_sink.withIndent(() {
_writeEnclosingElement(e);
_writeMetadata(e);
if (uri is DirectiveUriWithAugmentationImpl) {
_writeAugmentationElement(uri.augmentation);
}
});
}
void _writeAugmentationTarget(ElementImpl e) {
if (e is AugmentableElement && e.isAugmentation) {
if (e.augmentationTarget case var target?) {
_elementPrinter.writeNamedElement(
'augmentationTarget',
target,
);
} else if (e.augmentationTargetAny case var targetAny?) {
_elementPrinter.writeNamedElement(
'augmentationTargetAny',
targetAny,
);
}
}
}
void _writeAugmented(InstanceElementImpl e) {
if (e.augmentationTarget != null) {
return;
}
// No augmentation, not interesting.
if (e.augmentation == null) {
expect(e.augmented, TypeMatcher<NotAugmentedInstanceElementImpl>());
if (!configuration.withAugmentedWithoutAugmentation) {
return;
}
}
var augmented = e.augmented;
void writeFields() {
var sorted = augmented.fields.sortedBy((e) => e.name);
_elementPrinter.writeElementList('fields', sorted);
}
void writeConstructors() {
if (!configuration.withConstructors) {
return;
}
if (augmented is AugmentedInterfaceElementImpl) {
var sorted = augmented.constructors.sortedBy((e) => e.name);
expect(sorted, isNotEmpty);
_elementPrinter.writeElementList('constructors', sorted);
}
}
void writeAccessors() {
var sorted = augmented.accessors.sortedBy((e) => e.name);
_elementPrinter.writeElementList('accessors', sorted);
}
void writeMethods() {
var sorted = augmented.methods.sortedBy((e) => e.name);
_elementPrinter.writeElementList('methods', sorted);
}
_sink.writelnWithIndent('augmented');
_sink.withIndent(() {
switch (augmented) {
case AugmentedClassElement():
_elementPrinter.writeTypeList('mixins', augmented.mixins);
_elementPrinter.writeTypeList('interfaces', augmented.interfaces);
writeFields();
writeConstructors();
writeAccessors();
writeMethods();
case AugmentedEnumElement():
_elementPrinter.writeTypeList('mixins', augmented.mixins);
_elementPrinter.writeTypeList('interfaces', augmented.interfaces);
writeFields();
_elementPrinter.writeElementList(
'constants',
augmented.constants.sortedBy((e) => e.name),
);
writeConstructors();
writeAccessors();
writeMethods();
case AugmentedExtensionElement():
writeFields();
writeAccessors();
writeMethods();
case AugmentedExtensionTypeElement():
_elementPrinter.writeTypeList('interfaces', augmented.interfaces);
writeFields();
writeConstructors();
writeAccessors();
writeMethods();
case AugmentedMixinElement():
_elementPrinter.writeTypeList(
'superclassConstraints',
augmented.superclassConstraints,
);
_elementPrinter.writeTypeList('interfaces', augmented.interfaces);
writeFields();
writeAccessors();
writeMethods();
default:
// TODO(scheglov): Add other types and properties
throw UnimplementedError('${e.runtimeType}');
}
});
}
void _writeBodyModifiers(ExecutableElement e) {
if (e.isAsynchronous) {
expect(e.isSynchronous, isFalse);
_sink.write(' async');
}
if (e.isSynchronous && e.isGenerator) {
expect(e.isAsynchronous, isFalse);
_sink.write(' sync');
}
_sink.writeIf(e.isGenerator, '*');
if (e is ExecutableElementImpl && e.invokesSuperSelf) {
_sink.write(' invokesSuperSelf');
}
}
void _writeCodeRange(Element e) {
if (configuration.withCodeRanges && !e.isSynthetic) {
if (e is MaybeAugmentedInstanceElementMixin) {
e = e.declaration!;
}
e as ElementImpl;
_sink.writelnWithIndent('codeOffset: ${e.codeOffset}');
_sink.writelnWithIndent('codeLength: ${e.codeLength}');
}
}
void _writeConstantInitializer(Element e) {
if (configuration.withConstantInitializers) {
if (e is ConstVariableElement) {
var initializer = e.constantInitializer;
if (initializer != null) {
_sink.writelnWithIndent('constantInitializer');
_sink.withIndent(() {
_writeNode(initializer);
});
}
}
}
}
void _writeConstructorElement(ConstructorElement e) {
e as ConstructorElementImpl;
// Check that the reference exists, and filled with the element.
var reference = e.reference;
if (reference == null) {
fail('Every constructor must have a reference.');
}
_sink.writeIndentedLine(() {
_sink.writeIf(e.isAugmentation, 'augment ');
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isExternal, 'external ');
_sink.writeIf(e.isConst, 'const ');
_sink.writeIf(e.isFactory, 'factory ');
expect(e.isAbstract, isFalse);
_writeName(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeDisplayName(e);
var periodOffset = e.periodOffset;
var nameEnd = e.nameEnd;
if (periodOffset != null && nameEnd != null) {
_sink.writelnWithIndent('periodOffset: $periodOffset');
_sink.writelnWithIndent('nameEnd: $nameEnd');
}
_writeParameterElements(e.parameters);
_writeElements(
'constantInitializers',
e.constantInitializers,
_writeNode,
);
var superConstructor = e.superConstructor;
if (superConstructor != null) {
var enclosingElement = superConstructor.enclosingElement3;
if (enclosingElement is ClassElement &&
!enclosingElement.isDartCoreObject) {
_elementPrinter.writeNamedElement(
'superConstructor',
superConstructor,
);
}
}
var redirectedConstructor = e.redirectedConstructor;
if (redirectedConstructor != null) {
_elementPrinter.writeNamedElement(
'redirectedConstructor',
redirectedConstructor,
);
}
_writeNonSyntheticElement(e);
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
});
expect(e.isAsynchronous, isFalse);
expect(e.isGenerator, isFalse);
if (e.isSynthetic) {
expect(e.nameOffset, -1);
expect(e.nonSynthetic, same(e.enclosingElement3));
} else {
expect(e.nameOffset, isPositive);
}
}
void _writeDisplayName(Element e) {
if (configuration.withDisplayName) {
_sink.writelnWithIndent('displayName: ${e.displayName}');
}
}
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');
_sink.writelnWithIndent('documentationComment: $str');
}
}
void _writeEnclosingElement(ElementImpl e) {
_elementPrinter.writeNamedElement(
'enclosingElement',
// ignore: deprecated_member_use_from_same_package
e.enclosingElement,
);
switch (e) {
case CompilationUnitElementImpl():
if (identical(e.library.definingCompilationUnit, e)) {
expect(e.enclosingElement3, isNull);
} else {
expect(
e.enclosingElement3,
TypeMatcher<CompilationUnitElementImpl>(),
);
_elementPrinter.writeNamedElement(
'enclosingElement3',
e.enclosingElement3,
);
}
case LibraryImportElementImpl():
case LibraryExportElementImpl():
case PartElementImpl():
case PrefixElementImpl():
expect(
e.enclosingElement3,
TypeMatcher<CompilationUnitElementImpl>(),
);
_elementPrinter.writeNamedElement(
'enclosingElement3',
e.enclosingElement3,
);
default:
expect(e.enclosingElement3, same(e.enclosingElement3));
}
}
void _writeExportNamespace(LibraryElement e) {
var map = e.exportNamespace.definedNames;
var sortedEntries = map.entries.sortedBy((entry) => entry.key);
for (var entry in sortedEntries) {
_elementPrinter.writeNamedElement(entry.key, entry.value);
}
}
void _writeExtensionElement(ExtensionElementImpl e) {
_sink.writeIndentedLine(() {
_sink.writeIf(e.isAugmentation, 'augment ');
_writeName(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeTypeParameterElements(e.typeParameters);
if (e.augmentationTarget == null) {
_writeType('extendedType', e.extendedType);
}
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
_writeElements('fields', e.fields, _writePropertyInducingElement);
_writeElements('accessors', e.accessors, _writePropertyAccessorElement);
_writeMethods(e.methods);
_validateAugmentedInstanceElement(e);
_writeAugmented(e);
});
_assertNonSyntheticElementSelf(e);
}
void _writeFieldFormalParameterField(ParameterElement e) {
if (e is FieldFormalParameterElement) {
var field = e.field;
if (field != null) {
_elementPrinter.writeNamedElement('field', field);
} else {
_sink.writelnWithIndent('field: <null>');
}
}
}
void _writeFunctionElement(FunctionElementImpl e) {
expect(e.isStatic, isTrue);
_sink.writeIndentedLine(() {
_sink.writeIf(e.isAugmentation, 'augment ');
_sink.writeIf(e.isExternal, 'external ');
_writeName(e);
_writeBodyModifiers(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeTypeParameterElements(e.typeParameters);
_writeParameterElements(e.parameters);
_writeReturnType(e.returnType);
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
});
_assertNonSyntheticElementSelf(e);
}
void _writeImportElementPrefix(ImportElementPrefixImpl? prefix) {
if (prefix != null) {
_sink.writeIf(prefix is DeferredImportElementPrefix, ' deferred');
_sink.write(' as ');
_writeName(prefix.element);
}
}
void _writeInterfaceElement(InterfaceElementImpl e) {
_sink.writeIndentedLine(() {
if (e.isAugmentation) {
_sink.write('augment ');
}
switch (e) {
case ClassElementImpl():
_sink.writeIf(e.isAbstract, 'abstract ');
_sink.writeIf(e.isMacro, 'macro ');
_sink.writeIf(e.isSealed, 'sealed ');
_sink.writeIf(e.isBase, 'base ');
_sink.writeIf(e.isInterface, 'interface ');
_sink.writeIf(e.isFinal, 'final ');
_writeNotSimplyBounded(e);
_sink.writeIf(e.isMixinClass, 'mixin ');
_sink.write('class ');
_sink.writeIf(e.isMixinApplication, 'alias ');
case EnumElementImpl():
_writeNotSimplyBounded(e);
_sink.write('enum ');
case ExtensionTypeElementImpl():
_sink.writeIf(
e.hasRepresentationSelfReference,
'hasRepresentationSelfReference ',
);
_sink.writeIf(
e.hasImplementsSelfReference,
'hasImplementsSelfReference ',
);
_writeNotSimplyBounded(e);
case MixinElementImpl():
_sink.writeIf(e.isBase, 'base ');
_writeNotSimplyBounded(e);
_sink.write('mixin ');
}
_writeName(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeTypeParameterElements(e.typeParameters);
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
if (!e.isAugmentation) {
var supertype = e.supertype;
if (supertype != null &&
(supertype.element.name != 'Object' || e.mixins.isNotEmpty)) {
_writeType('supertype', supertype);
}
}
if (e is ExtensionTypeElementImpl) {
if (e.augmentationTarget == null) {
_elementPrinter.writeNamedElement('representation', e.representation);
_elementPrinter.writeNamedElement(
'primaryConstructor', e.primaryConstructor);
_elementPrinter.writeNamedType('typeErasure', e.typeErasure);
}
}
if (e is MixinElementImpl) {
_elementPrinter.writeTypeList(
'superclassConstraints',
e.superclassConstraints,
);
}
_elementPrinter.writeTypeList('mixins', e.mixins);
_elementPrinter.writeTypeList('interfaces', e.interfaces);
if (configuration.withAllSupertypes) {
var sorted = e.allSupertypes.sortedBy((t) => t.element.name);
_elementPrinter.writeTypeList('allSupertypes', sorted);
}
_writeElements('fields', e.fields, _writePropertyInducingElement);
var constructors = e.constructors;
if (e is MixinElement) {
expect(constructors, isEmpty);
} else if (configuration.withConstructors) {
_writeElements('constructors', constructors, _writeConstructorElement);
}
_writeElements('accessors', e.accessors, _writePropertyAccessorElement);
_writeMethods(e.methods);
_validateAugmentedInstanceElement(e);
_writeAugmented(e);
});
_assertNonSyntheticElementSelf(e);
}
void _writeLibraryAugmentations(LibraryElementImpl e) {
if (configuration.withLibraryAugmentations) {
var augmentations = e.augmentations;
if (augmentations.isNotEmpty) {
_sink.writelnWithIndent('augmentations');
_sink.withIndent(() {
for (var element in augmentations) {
_sink.writeIndent();
_elementPrinter.writeElement(element);
}
});
}
}
}
void _writeLibraryExportElement(LibraryExportElementImpl e) {
e.location;
_sink.writeIndentedLine(() {
_writeDirectiveUri(e.uri);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeMetadata(e);
_writeNamespaceCombinators(e.combinators);
});
_assertNonSyntheticElementSelf(e);
}
void _writeLibraryImportElement(LibraryImportElementImpl e) {
e.location;
_sink.writeIndentedLine(() {
_writeDirectiveUri(e.uri);
_sink.writeIf(e.isSynthetic, ' synthetic');
_writeImportElementPrefix(e.prefix);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeMetadata(e);
_writeNamespaceCombinators(e.combinators);
});
}
void _writeLibraryOrAugmentationElement(LibraryOrAugmentationElementImpl e) {
_writeReference(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
if (configuration.withImports) {
var imports = e.libraryImports.where((import) {
return configuration.withSyntheticDartCoreImport || !import.isSynthetic;
}).toList();
_writeElements(
'libraryImports',
imports,
_writeLibraryImportElement,
);
_writeElements('prefixes', e.prefixes, _writePrefixElement);
}
_writeElements(
'libraryExports',
e.libraryExports,
_writeLibraryExportElement,
);
var definingUnit = e.definingCompilationUnit;
expect(definingUnit.libraryOrAugmentationElement, same(e));
if (configuration.filter(definingUnit)) {
_elementPrinter.writeNamedElement('definingUnit', definingUnit);
}
if (e is LibraryElementImpl) {
_writeLibraryAugmentations(e);
}
_writeElements('augmentationImports', e.augmentationImports,
_writeAugmentationImportElement);
}
void _writeMacroDiagnostics(Element e) {
void writeTypeAnnotationLocation(TypeAnnotationLocation location) {
switch (location) {
case AliasedTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('AliasedTypeLocation');
case ElementTypeLocation():
_sink.writelnWithIndent('ElementTypeLocation');
_sink.withIndent(() {
_elementPrinter.writeNamedElement('element', location.element);
});
case ExtendsClauseTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('ExtendsClauseTypeLocation');
case FormalParameterTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('FormalParameterTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case ListIndexTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('ListIndexTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case RecordNamedFieldTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('RecordNamedFieldTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case RecordPositionalFieldTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('RecordPositionalFieldTypeLocation');
_sink.withIndent(() {
_sink.writelnWithIndent('index: ${location.index}');
});
case ReturnTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('ReturnTypeLocation');
case VariableTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('VariableTypeLocation');
default:
// TODO(scheglov): Handle this case.
throw UnimplementedError('${location.runtimeType}');
}
}
/// Returns `true` if patterns were printed.
/// Returns `false` if no patterns configured.
bool printMessagePatterns(String message) {
var patterns = configuration.macroDiagnosticMessagePatterns;
if (patterns == null) {
return false;
}
_sink.writelnWithIndent('contains');
_sink.withIndent(() {
for (var pattern in patterns) {
if (message.contains(pattern)) {
_sink.writelnWithIndent(pattern);
}
}
});
return true;
}
void writeMessage(MacroDiagnosticMessage object) {
// Write the message.
if (!printMessagePatterns(object.message)) {
var message = object.message;
const stackTraceText = '#0';
var stackTraceIndex = message.indexOf(stackTraceText);
if (stackTraceIndex >= 0) {
var end = stackTraceIndex + stackTraceText.length;
var withoutStackTrace = message.substring(0, end);
if (configuration.withMacroStackTraces) {
_sink.writelnWithIndent('message:\n$message');
} else {
_sink.writelnWithIndent('message:\n$withoutStackTrace <cut>');
}
} else {
_sink.writelnWithIndent('message: $message');
}
}
// Write the target.
var target = object.target;
switch (target) {
case ApplicationMacroDiagnosticTarget():
_sink.writelnWithIndent('target: ApplicationMacroDiagnosticTarget');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${target.annotationIndex}',
);
});
case ElementMacroDiagnosticTarget():
_sink.writelnWithIndent('target: ElementMacroDiagnosticTarget');
_sink.withIndent(() {
_elementPrinter.writeNamedElement('element', target.element);
});
case ElementAnnotationMacroDiagnosticTarget():
_sink.writelnWithIndent(
'target: ElementAnnotationMacroDiagnosticTarget',
);
_sink.withIndent(() {
_elementPrinter.writeNamedElement('element', target.element);
_sink.writelnWithIndent(
'annotationIndex: ${target.annotationIndex}',
);
});
case TypeAnnotationMacroDiagnosticTarget():
_sink.writelnWithIndent(
'target: TypeAnnotationMacroDiagnosticTarget',
);
_sink.withIndent(() {
writeTypeAnnotationLocation(target.location);
});
}
}
if (e case MacroTargetElement macroTarget) {
_sink.writeElements(
'macroDiagnostics',
macroTarget.macroDiagnostics,
(diagnostic) {
switch (diagnostic) {
case ArgumentMacroDiagnostic():
_sink.writelnWithIndent('ArgumentMacroDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_sink.writelnWithIndent(
'argumentIndex: ${diagnostic.argumentIndex}',
);
_sink.writelnWithIndent('message: ${diagnostic.message}');
});
case DeclarationsIntrospectionCycleDiagnostic():
_sink.writelnWithIndent(
'DeclarationsIntrospectionCycleDiagnostic',
);
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_elementPrinter.writeNamedElement(
'introspectedElement',
diagnostic.introspectedElement,
);
_sink.writeElements(
'components',
diagnostic.components,
(component) {
_sink.writelnWithIndent(
'DeclarationsIntrospectionCycleComponent',
);
_sink.withIndent(() {
_elementPrinter.writeNamedElement(
'element',
component.element,
);
_sink.writelnWithIndent(
'annotationIndex: ${component.annotationIndex}',
);
_elementPrinter.writeNamedElement(
'introspectedElement',
component.introspectedElement,
);
});
},
);
});
case ExceptionMacroDiagnostic():
_sink.writelnWithIndent('ExceptionMacroDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
if (!printMessagePatterns(diagnostic.message)) {
_sink.writelnWithIndent(
'message: ${diagnostic.message}',
);
}
if (configuration.withMacroStackTraces) {
_sink.writelnWithIndent(
'stackTrace:\n${diagnostic.stackTrace}',
);
}
});
case InvalidMacroTargetDiagnostic():
_sink.writelnWithIndent('InvalidMacroTargetDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_sink.writeElements(
'supportedKinds',
diagnostic.supportedKinds,
(kindName) {
_sink.writelnWithIndent(kindName);
},
);
});
case MacroDiagnostic():
_sink.writelnWithIndent('MacroDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent('message: MacroDiagnosticMessage');
_sink.withIndent(() {
writeMessage(diagnostic.message);
});
_sink.writeElements(
'contextMessages',
diagnostic.contextMessages,
(message) {
_sink.writelnWithIndent('MacroDiagnosticMessage');
_sink.withIndent(() {
writeMessage(message);
});
},
);
_sink.writelnWithIndent(
'severity: ${diagnostic.severity.name}',
);
if (diagnostic.correctionMessage case var correctionMessage?) {
_sink.writelnWithIndent(
'correctionMessage: $correctionMessage',
);
}
});
case NotAllowedDeclarationDiagnostic():
_sink.writelnWithIndent('NotAllowedDeclarationDiagnostic');
_sink.withIndent(() {
_sink.writelnWithIndent(
'annotationIndex: ${diagnostic.annotationIndex}',
);
_sink.writelnWithIndent(
'phase: ${diagnostic.phase.name}',
);
var nodeRangesStr = diagnostic.nodeRanges
.map((r) => '(${r.offset}, ${r.length})')
.join(' ');
_sink.writelnWithIndent('nodeRanges: $nodeRangesStr');
_sink.writeln('---');
_sink.write(diagnostic.code);
_sink.writeln('---');
});
}
},
);
}
}
void _writeMetadata(Element element) {
if (configuration.withMetadata) {
var annotations = element.metadata;
if (annotations.isNotEmpty) {
_sink.writelnWithIndent('metadata');
_sink.withIndent(() {
for (var annotation in annotations) {
annotation as ElementAnnotationImpl;
_writeNode(annotation.annotationAst);
}
});
}
}
}
void _writeMethodElement(MethodElementImpl e) {
_sink.writeIndentedLine(() {
_sink.writeIf(e.isAugmentation, 'augment ');
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e.isAbstract, 'abstract ');
_sink.writeIf(e.isExternal, 'external ');
_writeName(e);
_writeBodyModifiers(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeTypeInferenceError(e);
_writeTypeParameterElements(e.typeParameters);
_writeParameterElements(e.parameters);
_writeReturnType(e.returnType);
_writeNonSyntheticElement(e);
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
});
if (e.isSynthetic && e.enclosingElement3 is EnumElementImpl) {
expect(e.name, 'toString');
expect(e.nonSynthetic, same(e.enclosingElement3));
} else {
_assertNonSyntheticElementSelf(e);
}
}
void _writeMethods(List<MethodElementImpl> elements) {
_writeElements('methods', elements, _writeMethodElement);
}
void _writeName(Element e) {
String name;
switch (e) {
case ExtensionElement(name: null):
name = '<null>';
default:
name = e.name!;
}
if (e is PropertyAccessorElement && e.isSetter) {
expect(name, endsWith('='));
}
_sink.write(name);
_sink.write(name.isNotEmpty ? ' @' : '@');
_sink.write(e.nameOffset);
}
void _writeNamespaceCombinator(NamespaceCombinator e) {
_sink.writeIndentedLine(() {
switch (e) {
case ShowElementCombinator():
_sink.write('show: ');
_sink.write(e.shownNames.join(', '));
case HideElementCombinator():
_sink.write('hide: ');
_sink.write(e.hiddenNames.join(', '));
}
});
}
void _writeNamespaceCombinators(List<NamespaceCombinator> elements) {
_writeElements('combinators', elements, _writeNamespaceCombinator);
}
void _writeNonSyntheticElement(Element e) {
if (configuration.withNonSynthetic) {
_elementPrinter.writeNamedElement('nonSynthetic', e.nonSynthetic);
}
}
void _writeNotSimplyBounded(InterfaceElementImpl e) {
if (e.isAugmentation) {
return;
}
_sink.writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
}
void _writeParameterElement(ParameterElement e) {
e as ParameterElementImpl;
if (e.isNamed && e.enclosingElement3 is ExecutableElement) {
expect(e.reference, isNotNull);
} else {
expect(e.reference, isNull);
}
_sink.writeIndentedLine(() {
if (e.isRequiredPositional) {
_sink.write('requiredPositional ');
} else if (e.isOptionalPositional) {
_sink.write('optionalPositional ');
} else if (e.isRequiredNamed) {
_sink.write('requiredNamed ');
} else if (e.isOptionalNamed) {
_sink.write('optionalNamed ');
}
if (e is ConstVariableElement) {
_sink.write('default ');
}
_sink.writeIf(e.isConst, 'const ');
_sink.writeIf(e.isCovariant, 'covariant ');
_sink.writeIf(e.isFinal, 'final ');
if (e is FieldFormalParameterElement) {
_sink.write('this.');
} else if (e is SuperFormalParameterElement) {
_sink.writeIf(e.hasDefaultValue, 'hasDefaultValue ');
_sink.write('super.');
}
_writeName(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeType('type', e.type);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeTypeParameterElements(e.typeParameters);
_writeParameterElements(e.parameters);
_writeConstantInitializer(e);
_writeNonSyntheticElement(e);
_writeFieldFormalParameterField(e);
_writeSuperConstructorParameter(e);
});
}
void _writeParameterElements(List<ParameterElement> elements) {
_writeElements('parameters', elements, _writeParameterElement);
}
void _writePartElement(PartElementImpl e) {
_sink.writelnWithIndent(_idMap[e]);
_sink.withIndent(() {
var uri = e.uri;
_sink.writeIndentedLine(() {
_sink.write('uri: ');
_writeDirectiveUri(e.uri);
});
_writeEnclosingElement(e);
_writeMetadata(e);
if (uri is DirectiveUriWithUnitImpl) {
_elementPrinter.writeNamedElement('unit', uri.unit);
}
});
}
void _writePrefixElement(PrefixElementImpl e) {
_sink.writeIndentedLine(() {
_writeName(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
});
}
void _writePropertyAccessorElement(PropertyAccessorElement e) {
e as PropertyAccessorElementImpl;
var variable = e.variable2;
if (variable != null) {
var variableEnclosing = variable.enclosingElement3;
if (variableEnclosing is CompilationUnitElement) {
expect(variableEnclosing.topLevelVariables, contains(variable));
} else if (variableEnclosing is InterfaceElement) {
expect(variableEnclosing.fields, contains(variable));
}
} else {
expect(e.isAugmentation, isTrue);
expect(e.augmentationTarget, isNull);
}
if (e.isSynthetic) {
expect(e.nameOffset, -1);
} else {
expect(e.nameOffset, isPositive);
_assertNonSyntheticElementSelf(e);
}
_sink.writeIndentedLine(() {
_sink.writeIf(e.isAugmentation, 'augment ');
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e.isAbstract, 'abstract ');
_sink.writeIf(e.isExternal, 'external ');
if (e.isGetter) {
_sink.write('get ');
} else {
_sink.write('set ');
}
_writeName(e);
_writeBodyModifiers(e);
});
void writeLinking() {
if (configuration.withPropertyLinking) {
_sink.writelnWithIndent('id: ${_idMap[e]}');
if (e.variable2 case var variable?) {
_sink.writelnWithIndent('variable: ${_idMap[variable]}');
} else {
_sink.writelnWithIndent('variable: <null>');
}
}
}
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
expect(e.typeParameters, isEmpty);
_writeParameterElements(e.parameters);
_writeReturnType(e.returnType);
_writeNonSyntheticElement(e);
writeLinking();
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
});
}
void _writePropertyInducingElement(PropertyInducingElement e) {
e as PropertyInducingElementImpl;
DartType type = e.type;
expect(type, isNotNull);
if (e.isSynthetic) {
expect(e.nameOffset, -1);
} else {
if (!e.isAugmentation) {
expect(e.getter, isNotNull);
}
expect(e.nameOffset, isPositive);
_assertNonSyntheticElementSelf(e);
}
_sink.writeIndentedLine(() {
_sink.writeIf(e.isAugmentation, 'augment ');
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e is FieldElementImpl && e.isAbstract, 'abstract ');
_sink.writeIf(e is FieldElementImpl && e.isCovariant, 'covariant ');
_sink.writeIf(e is FieldElementImpl && e.isExternal, 'external ');
_sink.writeIf(e.isLate, 'late ');
_sink.writeIf(e.isFinal, 'final ');
_sink.writeIf(e.isConst, 'const ');
if (e is FieldElementImpl) {
_sink.writeIf(e.isEnumConstant, 'enumConstant ');
_sink.writeIf(e.isPromotable, 'promotable ');
}
_writeName(e);
});
void writeLinking() {
if (configuration.withPropertyLinking) {
_sink.writelnWithIndent('id: ${_idMap[e]}');
var getter = e.getter;
if (getter != null) {
_sink.writelnWithIndent('getter: ${_idMap[getter]}');
}
var setter = e.setter;
if (setter != null) {
_sink.writelnWithIndent('setter: ${_idMap[setter]}');
}
}
}
_sink.withIndent(() {
_writeReference(e);
_writeEnclosingElement(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeTypeInferenceError(e);
_writeType('type', e.type);
_writeShouldUseTypeForInitializerInference(e);
_writeConstantInitializer(e);
_writeNonSyntheticElement(e);
writeLinking();
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
});
}
void _writeReturnType(DartType type) {
if (configuration.withReturnType) {
_writeType('returnType', type);
}
}
void _writeShouldUseTypeForInitializerInference(
PropertyInducingElementImpl e,
) {
if (e.isSynthetic) return;
if (!e.hasInitializer) return;
_sink.writelnWithIndent(
'shouldUseTypeForInitializerInference: '
'${e.shouldUseTypeForInitializerInference}',
);
}
void _writeSinceSdkVersion(Element e) {
var sinceSdkVersion = e.sinceSdkVersion;
if (sinceSdkVersion != null) {
_sink.writelnWithIndent('sinceSdkVersion: $sinceSdkVersion');
}
}
void _writeSuperConstructorParameter(ParameterElement e) {
if (e is SuperFormalParameterElement) {
var superParameter = e.superConstructorParameter;
if (superParameter != null) {
_elementPrinter.writeNamedElement(
'superConstructorParameter',
superParameter,
);
} else {
_sink.writelnWithIndent('superConstructorParameter: <null>');
}
}
}
void _writeType(String name, DartType type) {
_elementPrinter.writeNamedType(name, type);
if (configuration.withFunctionTypeParameters) {
if (type is FunctionType) {
_sink.withIndent(() {
_writeParameterElements(type.parameters);
});
}
}
}
void _writeTypeAliasElement(TypeAliasElement e) {
e as TypeAliasElementImpl;
_sink.writeIndentedLine(() {
_sink.writeIf(e.isAugmentation, 'augment ');
_sink.writeIf(e.isFunctionTypeAliasBased, 'functionTypeAliasBased ');
_sink.writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
_writeName(e);
});
_sink.withIndent(() {
_writeReference(e);
_writeDocumentation(e);
_writeMetadata(e);
_writeSinceSdkVersion(e);
_writeCodeRange(e);
_writeTypeParameterElements(e.typeParameters);
var aliasedType = e.aliasedType;
_writeType('aliasedType', aliasedType);
var aliasedElement = e.aliasedElement;
if (aliasedElement is GenericFunctionTypeElementImpl) {
_sink.writelnWithIndent('aliasedElement: GenericFunctionTypeElement');
_sink.withIndent(() {
_writeTypeParameterElements(aliasedElement.typeParameters);
_writeParameterElements(aliasedElement.parameters);
_writeReturnType(aliasedElement.returnType);
});
}
_writeMacroDiagnostics(e);
_writeAugmentationTarget(e);
_writeAugmentation(e);
});
_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);
}
_sink.writelnWithIndent('typeInferenceError: $kindName');
_sink.withIndent(() {
if (kindName == 'dependencyCycle') {
_sink.writelnWithIndent('arguments: ${inferenceError?.arguments}');
}