81845864ca
TEST=existing Change-Id: I8726c936261ceb770b489f264d14fff02a1b4998 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/275243 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com> Reviewed-by: Jens Johansen <jensj@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
330 lines
10 KiB
Dart
330 lines
10 KiB
Dart
// Copyright (c) 2020, 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 '../ast.dart';
|
|
|
|
String nullabilityToString(Nullability nullability) {
|
|
switch (nullability) {
|
|
case Nullability.legacy:
|
|
return '*';
|
|
case Nullability.nullable:
|
|
return '?';
|
|
case Nullability.undetermined:
|
|
return '%';
|
|
case Nullability.nonNullable:
|
|
return '';
|
|
}
|
|
}
|
|
|
|
String nameToString(Name? node, {bool includeLibraryName = false}) {
|
|
if (node == null) {
|
|
return 'null';
|
|
} else if (node.library != null && includeLibraryName) {
|
|
return '${libraryNameToString(node.library)}::${node.text}';
|
|
} else {
|
|
return node.text;
|
|
}
|
|
}
|
|
|
|
String libraryNameToString(Library? node) {
|
|
return node == null ? 'null' : node.name ?? 'library ${node.importUri}';
|
|
}
|
|
|
|
String qualifiedClassNameToString(Class node,
|
|
{bool includeLibraryName = false}) {
|
|
TreeNode? parent = node.parent;
|
|
if (parent is Library && includeLibraryName) {
|
|
return libraryNameToString(parent) + '::' + classNameToString(node);
|
|
} else {
|
|
return classNameToString(node);
|
|
}
|
|
}
|
|
|
|
String qualifiedCanonicalNameToString(CanonicalName canonicalName,
|
|
{bool includeLibraryName = false,
|
|
bool includeLibraryNamesInTypes = false}) {
|
|
if (canonicalName.isRoot) {
|
|
return '<root>';
|
|
} else if (canonicalName.parent!.isRoot) {
|
|
// Library.
|
|
return 'library ${canonicalName.name}';
|
|
} else if (canonicalName.parent!.parent!.isRoot) {
|
|
// Class or extension.
|
|
if (!includeLibraryName) {
|
|
return canonicalName.name;
|
|
}
|
|
String parentName = qualifiedCanonicalNameToString(canonicalName.parent!,
|
|
includeLibraryName: includeLibraryName,
|
|
includeLibraryNamesInTypes: includeLibraryNamesInTypes);
|
|
return '$parentName::${canonicalName.name}';
|
|
} else {
|
|
// Constructor, field, procedure (factory, getter, setter etc), typedef;
|
|
// but we could technically be anywhere in the "hierarchy" --- at the
|
|
// @typedef for instance, or at the uri of a library for a private name.
|
|
CanonicalName parentNotPrivateUri = canonicalName.parent!;
|
|
if (canonicalName.name.startsWith("_")) {
|
|
parentNotPrivateUri = parentNotPrivateUri.parent!;
|
|
}
|
|
if (parentNotPrivateUri.name == CanonicalName.typedefsName) {
|
|
includeLibraryName = includeLibraryNamesInTypes;
|
|
}
|
|
if (parentNotPrivateUri.parent!.parent!.parent?.isRoot == true) {
|
|
// Parent is class (or extension).
|
|
String parentName = qualifiedCanonicalNameToString(
|
|
parentNotPrivateUri.parent!,
|
|
includeLibraryName: includeLibraryName,
|
|
includeLibraryNamesInTypes: includeLibraryNamesInTypes);
|
|
return "$parentName.${canonicalName.name}";
|
|
} else {
|
|
// Parent is library.
|
|
if (!includeLibraryName) {
|
|
return canonicalName.name;
|
|
}
|
|
String parentName = qualifiedCanonicalNameToString(
|
|
parentNotPrivateUri.parent!,
|
|
includeLibraryName: includeLibraryName,
|
|
includeLibraryNamesInTypes: includeLibraryNamesInTypes);
|
|
return '$parentName::${canonicalName.name}';
|
|
}
|
|
}
|
|
}
|
|
|
|
String qualifiedClassNameToStringByReference(Reference? reference,
|
|
{bool includeLibraryName = false}) {
|
|
if (reference == null) {
|
|
return '<missing-class-reference>';
|
|
} else {
|
|
Class? node = reference.node as Class?;
|
|
if (node != null) {
|
|
return qualifiedClassNameToString(node,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
CanonicalName? canonicalName = reference.canonicalName;
|
|
if (canonicalName != null) {
|
|
return qualifiedCanonicalNameToString(canonicalName,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
return '<unlinked-class-reference>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String classNameToString(Class? node) {
|
|
return node == null ? 'null' : node.name;
|
|
}
|
|
|
|
String qualifiedExtensionNameToString(Extension node,
|
|
{bool includeLibraryName = false}) {
|
|
TreeNode? parent = node.parent;
|
|
if (parent is Library && includeLibraryName) {
|
|
return libraryNameToString(parent) + '::' + extensionNameToString(node);
|
|
} else {
|
|
return extensionNameToString(node);
|
|
}
|
|
}
|
|
|
|
String qualifiedExtensionNameToStringByReference(Reference? reference,
|
|
{bool includeLibraryName = false}) {
|
|
if (reference == null) {
|
|
return '<missing-extension-reference>';
|
|
} else {
|
|
Extension? node = reference.node as Extension?;
|
|
if (node != null) {
|
|
return qualifiedExtensionNameToString(node,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
CanonicalName? canonicalName = reference.canonicalName;
|
|
if (canonicalName != null) {
|
|
return qualifiedCanonicalNameToString(canonicalName,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
return '<unlinked-extension-reference>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String extensionNameToString(Extension? node) {
|
|
return node == null ? 'null' : node.name;
|
|
}
|
|
|
|
String qualifiedInlineClassNameToString(InlineClass node,
|
|
{bool includeLibraryName = false}) {
|
|
TreeNode? parent = node.parent;
|
|
if (parent is Library && includeLibraryName) {
|
|
return libraryNameToString(parent) + '::' + inlineClassNameToString(node);
|
|
} else {
|
|
return inlineClassNameToString(node);
|
|
}
|
|
}
|
|
|
|
String qualifiedInlineClassNameToStringByReference(Reference? reference,
|
|
{bool includeLibraryName = false}) {
|
|
if (reference == null) {
|
|
return '<missing-inline-class-reference>';
|
|
} else {
|
|
InlineClass? node = reference.node as InlineClass?;
|
|
if (node != null) {
|
|
return qualifiedInlineClassNameToString(node,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
CanonicalName? canonicalName = reference.canonicalName;
|
|
if (canonicalName != null) {
|
|
return qualifiedCanonicalNameToString(canonicalName,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
return '<unlinked-inline-class-reference>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String inlineClassNameToString(InlineClass? node) {
|
|
return node == null ? 'null' : node.name;
|
|
}
|
|
|
|
String qualifiedTypedefNameToString(Typedef node,
|
|
{bool includeLibraryName = false}) {
|
|
TreeNode? parent = node.parent;
|
|
if (parent is Library && includeLibraryName) {
|
|
return libraryNameToString(parent) + '::' + typedefNameToString(node);
|
|
} else {
|
|
return typedefNameToString(node);
|
|
}
|
|
}
|
|
|
|
String qualifiedTypedefNameToStringByReference(Reference? reference,
|
|
{bool includeLibraryName = false}) {
|
|
if (reference == null) {
|
|
return '<missing-typedef-reference>';
|
|
} else {
|
|
Typedef? node = reference.node as Typedef?;
|
|
if (node != null) {
|
|
return qualifiedTypedefNameToString(node,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
CanonicalName? canonicalName = reference.canonicalName;
|
|
if (canonicalName != null) {
|
|
return qualifiedCanonicalNameToString(canonicalName,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
return '<unlinked-typedef-reference>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String typedefNameToString(Typedef? node) {
|
|
return node == null ? 'null' : node.name;
|
|
}
|
|
|
|
String qualifiedMemberNameToString(Member node,
|
|
{bool includeLibraryName = false}) {
|
|
TreeNode? parent = node.parent;
|
|
if (parent is Class) {
|
|
return qualifiedClassNameToString(parent,
|
|
includeLibraryName: includeLibraryName) +
|
|
'.' +
|
|
memberNameToString(node);
|
|
} else if (parent is Library && includeLibraryName) {
|
|
return libraryNameToString(parent) + '::' + memberNameToString(node);
|
|
} else {
|
|
return memberNameToString(node);
|
|
}
|
|
}
|
|
|
|
String qualifiedMemberNameToStringByReference(Reference? reference,
|
|
{bool includeLibraryName = false}) {
|
|
if (reference == null) {
|
|
return '<missing-member-reference>';
|
|
} else {
|
|
Member? node = reference.node as Member?;
|
|
if (node != null) {
|
|
return qualifiedMemberNameToString(node,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
CanonicalName? canonicalName = reference.canonicalName;
|
|
if (canonicalName != null) {
|
|
return qualifiedCanonicalNameToString(canonicalName,
|
|
includeLibraryName: includeLibraryName);
|
|
} else {
|
|
return '<unlinked-member-reference>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String memberNameToString(Member node) {
|
|
return node.name.text;
|
|
}
|
|
|
|
String qualifiedTypeParameterNameToString(TypeParameter node,
|
|
{bool includeLibraryName = false}) {
|
|
TreeNode? parent = node.parent;
|
|
if (parent is Class) {
|
|
return qualifiedClassNameToString(parent,
|
|
includeLibraryName: includeLibraryName) +
|
|
'.' +
|
|
typeParameterNameToString(node);
|
|
} else if (parent is Extension) {
|
|
return qualifiedExtensionNameToString(parent,
|
|
includeLibraryName: includeLibraryName) +
|
|
'.' +
|
|
typeParameterNameToString(node);
|
|
} else if (parent is Member) {
|
|
return qualifiedMemberNameToString(parent,
|
|
includeLibraryName: includeLibraryName) +
|
|
'.' +
|
|
typeParameterNameToString(node);
|
|
}
|
|
return typeParameterNameToString(node);
|
|
}
|
|
|
|
String typeParameterNameToString(TypeParameter node) {
|
|
return node.name ??
|
|
"null-named TypeParameter ${node.runtimeType} ${node.hashCode}";
|
|
}
|
|
|
|
String? getEscapedCharacter(int codeUnit) {
|
|
switch (codeUnit) {
|
|
case 9:
|
|
return r'\t';
|
|
case 10:
|
|
return r'\n';
|
|
case 11:
|
|
return r'\v';
|
|
case 12:
|
|
return r'\f';
|
|
case 13:
|
|
return r'\r';
|
|
case 34:
|
|
return r'\"';
|
|
case 36:
|
|
return r'\$';
|
|
case 92:
|
|
return r'\\';
|
|
default:
|
|
if (codeUnit < 32 || codeUnit > 126) {
|
|
return r'\u' + '$codeUnit'.padLeft(4, '0');
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
String escapeString(String string) {
|
|
StringBuffer? buffer;
|
|
for (int i = 0; i < string.length; ++i) {
|
|
String? character = getEscapedCharacter(string.codeUnitAt(i));
|
|
if (character != null) {
|
|
buffer ??= new StringBuffer(string.substring(0, i));
|
|
buffer.write(character);
|
|
} else {
|
|
buffer?.write(string[i]);
|
|
}
|
|
}
|
|
return buffer == null ? string : buffer.toString();
|
|
}
|