[kernel] Refactor CanonicalName/Reference integration

The CL is a step towards have a more restricted and wellstructured
handled of references and canonical names.

The CL moves Reference to canonical_name.dart and makes
CanonicalName.reference private, and replaces CanonicalName.getReference
with a 'reference' getter.

It also removes NamedNode.canonicalName, Field.getterCanonicalName and
Field.setterCanonicalName so that these can only be accessed through the
corresponding reference. This is to reduce the reliance on the
canonical names which, ideally, should only be part of serialization and
deserialization.

TEST=existing

Change-Id: I955fb7d52d4e112d8741f7c12dcf38b74ae0c91a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/190442
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
Johnni Winther 2021-03-10 15:39:28 +00:00 committed by commit-bot@chromium.org
parent 0fa2fde5aa
commit 1aa6f00107
13 changed files with 450 additions and 393 deletions

View file

@ -53,7 +53,7 @@ String getTopLevelName(NamedNode n) {
if (n is Class) return n.name;
if (n is Typedef) return n.name;
if (n is Field) return n.name.text;
return n.canonicalName?.name;
return n.reference.canonicalName?.name;
}
/// Given an annotated [node] and a [test] function, returns the first matching

View file

@ -19,8 +19,6 @@ import 'package:front_end/src/fasta/source/source_loader.dart';
import 'package:kernel/binary/ast_from_binary.dart'
show
BinaryBuilderWithMetadata,
CanonicalNameError,
CanonicalNameSdkError,
CompilationModeError,
InvalidKernelSdkVersionError,
InvalidKernelVersionError,
@ -52,6 +50,9 @@ import 'package:kernel/kernel.dart'
TreeNode,
TypeParameter;
import 'package:kernel/canonical_name.dart'
show CanonicalNameError, CanonicalNameSdkError;
import 'package:kernel/kernel.dart' as kernel show Combinator;
import 'package:kernel/target/changed_structure_notifier.dart'

View file

@ -804,6 +804,7 @@ ordered
orders
ordinal
org
orphancy
orphans
ors
os
@ -994,6 +995,7 @@ replaces
replicated
repo
repositories
repurposed
requirement
res
residue

View file

@ -72,8 +72,8 @@ import 'dart:convert' show utf8;
import 'visitor.dart';
export 'visitor.dart';
import 'canonical_name.dart' show CanonicalName;
export 'canonical_name.dart' show CanonicalName;
import 'canonical_name.dart' show CanonicalName, Reference;
export 'canonical_name.dart' show CanonicalName, Reference;
import 'default_language_version.dart' show defaultLanguageVersion;
export 'default_language_version.dart' show defaultLanguageVersion;
@ -217,8 +217,6 @@ abstract class NamedNode extends TreeNode {
}
}
CanonicalName? get canonicalName => reference.canonicalName;
/// This is an advanced feature.
///
/// See [Component.relink] for a comprehensive description.
@ -240,162 +238,6 @@ abstract class Annotatable extends TreeNode {
void addAnnotation(Expression node);
}
/// Indirection between a reference and its definition.
///
/// There is only one reference object per [NamedNode].
class Reference {
CanonicalName? canonicalName;
NamedNode? _node;
NamedNode? get node {
if (_node == null) {
// Either this is an unbound reference or it belongs to a lazy-loaded
// (and not yet loaded) class. If it belongs to a lazy-loaded class,
// load the class.
CanonicalName? canonicalNameParent = canonicalName?.parent;
while (canonicalNameParent != null) {
if (canonicalNameParent.name.startsWith("@")) {
break;
}
canonicalNameParent = canonicalNameParent.parent;
}
if (canonicalNameParent != null) {
NamedNode? parentNamedNode =
canonicalNameParent.parent?.reference?._node;
if (parentNamedNode is Class) {
Class parentClass = parentNamedNode;
if (parentClass.lazyBuilder != null) {
parentClass.ensureLoaded();
}
}
}
}
return _node;
}
void set node(NamedNode? node) {
_node = node;
}
String toString() {
return "Reference to ${toStringInternal()}";
}
String toStringInternal() {
if (canonicalName != null) {
return '${canonicalName!.toStringInternal()}';
}
if (node != null) {
return node!.toStringInternal();
}
return 'Unbound reference';
}
Library get asLibrary {
if (node == null) {
throw '$this is not bound to an AST node. A library was expected';
}
return node as Library;
}
Class get asClass {
if (node == null) {
throw '$this is not bound to an AST node. A class was expected';
}
return node as Class;
}
Member get asMember {
if (node == null) {
throw '$this is not bound to an AST node. A member was expected';
}
return node as Member;
}
Field get asField {
if (node == null) {
throw '$this is not bound to an AST node. A field was expected';
}
return node as Field;
}
Constructor get asConstructor {
if (node == null) {
throw '$this is not bound to an AST node. A constructor was expected';
}
return node as Constructor;
}
Procedure get asProcedure {
if (node == null) {
throw '$this is not bound to an AST node. A procedure was expected';
}
return node as Procedure;
}
Typedef get asTypedef {
if (node == null) {
throw '$this is not bound to an AST node. A typedef was expected';
}
return node as Typedef;
}
Extension get asExtension {
if (node == null) {
throw '$this is not bound to an AST node. An extension was expected';
}
return node as Extension;
}
bool get isConsistent {
NamedNode? node = _node;
if (node != null) {
if (node.reference != this &&
(node is! Field || node.setterReference != this)) {
// The reference of a [NamedNode] must point to this reference, or
// if the node is a [Field] the setter reference must point to this
// reference.
return false;
}
}
if (canonicalName != null && canonicalName!.reference != this) {
return false;
}
return true;
}
String getInconsistency() {
StringBuffer sb = new StringBuffer();
sb.write('Reference ${this} (${hashCode}):');
NamedNode? node = _node;
if (node != null) {
if (node is Field) {
if (node.getterReference != this && node.setterReference != this) {
sb.write(' _node=${node} (${node.runtimeType}:${node.hashCode})');
sb.write(' _node.getterReference='
'${node.getterReference} (${node.getterReference.hashCode})');
sb.write(' _node.setterReference='
'${node.setterReference} (${node.setterReference.hashCode})');
}
} else {
if (node.reference != this) {
sb.write(' _node=${node} (${node.runtimeType}:${node.hashCode})');
sb.write(' _node.reference='
'${node.reference} (${node.reference.hashCode})');
}
}
}
if (canonicalName != null && canonicalName!.reference != this) {
sb.write(' canonicalName=${canonicalName} (${canonicalName.hashCode})');
sb.write(' canonicalName.reference='
'${canonicalName!.reference} (${canonicalName!.reference.hashCode})');
}
return sb.toString();
}
}
// ------------------------------------------------------------------------
// LIBRARIES and CLASSES
// ------------------------------------------------------------------------
@ -592,7 +434,7 @@ class Library extends NamedNode
}
void computeCanonicalNames() {
CanonicalName canonicalName = this.canonicalName!;
CanonicalName canonicalName = this.reference.canonicalName!;
for (int i = 0; i < typedefs.length; ++i) {
Typedef typedef_ = typedefs[i];
canonicalName.getChildFromTypedef(typedef_).bindTo(typedef_.reference);
@ -1317,7 +1159,7 @@ class Class extends NamedNode implements Annotatable, FileUriNode {
}
void computeCanonicalNames() {
CanonicalName canonicalName = this.canonicalName!;
CanonicalName canonicalName = this.reference.canonicalName!;
if (!dirty) return;
for (int i = 0; i < fields.length; ++i) {
Field member = fields[i];
@ -1886,14 +1728,6 @@ class Field extends Member {
Reference get getterReference => super.reference;
@override
@Deprecated(
"Use the specific getterCanonicalName/setterCanonicalName instead")
CanonicalName? get canonicalName => reference.canonicalName;
CanonicalName? get getterCanonicalName => getterReference.canonicalName;
CanonicalName? get setterCanonicalName => setterReference?.canonicalName;
Field.mutable(Name? name,
{this.type: const DynamicType(),
this.initializer,
@ -13189,9 +13023,9 @@ Reference getNonNullableClassReference(Class class_) {
CanonicalName getCanonicalNameOfMemberGetter(Member member) {
CanonicalName? canonicalName;
if (member is Field) {
canonicalName = member.getterCanonicalName;
canonicalName = member.getterReference.canonicalName;
} else {
canonicalName = member.canonicalName;
canonicalName = member.reference.canonicalName;
}
if (canonicalName == null) {
throw '$member has no canonical name';
@ -13204,9 +13038,9 @@ CanonicalName getCanonicalNameOfMemberGetter(Member member) {
CanonicalName getCanonicalNameOfMemberSetter(Member member) {
CanonicalName? canonicalName;
if (member is Field) {
canonicalName = member.setterCanonicalName;
canonicalName = member.setterReference!.canonicalName;
} else {
canonicalName = member.canonicalName;
canonicalName = member.reference.canonicalName;
}
if (canonicalName == null) {
throw '$member has no canonical name';
@ -13217,28 +13051,28 @@ CanonicalName getCanonicalNameOfMemberSetter(Member member) {
/// Returns the canonical name of [class_], or throws an exception if the
/// class has not been assigned a canonical name yet.
CanonicalName getCanonicalNameOfClass(Class class_) {
if (class_.canonicalName == null) {
if (class_.reference.canonicalName == null) {
throw '$class_ has no canonical name';
}
return class_.canonicalName!;
return class_.reference.canonicalName!;
}
/// Returns the canonical name of [extension], or throws an exception if the
/// class has not been assigned a canonical name yet.
CanonicalName getCanonicalNameOfExtension(Extension extension) {
if (extension.canonicalName == null) {
if (extension.reference.canonicalName == null) {
throw '$extension has no canonical name';
}
return extension.canonicalName!;
return extension.reference.canonicalName!;
}
/// Returns the canonical name of [library], or throws an exception if the
/// library has not been assigned a canonical name yet.
CanonicalName getCanonicalNameOfLibrary(Library library) {
if (library.canonicalName == null) {
if (library.reference.canonicalName == null) {
throw '$library has no canonical name';
}
return library.canonicalName!;
return library.reference.canonicalName!;
}
/// Murmur-inspired hashing, with a fall-back to Jenkins-inspired hashing when
@ -13375,10 +13209,10 @@ bool mapEquals(Map a, Map b) {
/// Returns the canonical name of [typedef_], or throws an exception if the
/// typedef has not been assigned a canonical name yet.
CanonicalName getCanonicalNameOfTypedef(Typedef typedef_) {
if (typedef_.canonicalName == null) {
if (typedef_.reference.canonicalName == null) {
throw '$typedef_ has no canonical name';
}
return typedef_.canonicalName!;
return typedef_.reference.canonicalName!;
}
/// Annotation describing information which is not part of Dart semantics; in

View file

@ -60,20 +60,6 @@ class CompilationModeError {
String toString() => "CompilationModeError[$message]";
}
class CanonicalNameError {
final String message;
CanonicalNameError(this.message);
String toString() => 'CanonicalNameError: $message';
}
class CanonicalNameSdkError extends CanonicalNameError {
CanonicalNameSdkError(String message) : super(message);
String toString() => 'CanonicalNameSdkError: $message';
}
class _ComponentIndex {
static const int numberOfFixedFields = 10;
@ -441,8 +427,7 @@ class BinaryBuilder {
final int fieldValueCount = readUInt30();
final Map<Reference, Constant> fieldValues = <Reference, Constant>{};
for (int i = 0; i < fieldValueCount; i++) {
final Reference fieldRef =
readNonNullCanonicalNameReference().getReference();
final Reference fieldRef = readNonNullCanonicalNameReference().reference;
final Constant constant = readConstantReference();
fieldValues[fieldRef] = constant;
}
@ -457,8 +442,7 @@ class BinaryBuilder {
}
Constant _readTearOffConstant() {
final Reference reference =
readNonNullCanonicalNameReference().getReference();
final Reference reference = readNonNullCanonicalNameReference().reference;
return new TearOffConstant.byReference(reference);
}
@ -656,7 +640,7 @@ class BinaryBuilder {
}
if (checkCanonicalNames) {
_checkCanonicalNameChildren(component.root);
component.root.checkCanonicalNameChildren();
}
return views;
});
@ -706,61 +690,10 @@ class BinaryBuilder {
}
if (checkCanonicalNames) {
_checkCanonicalNameChildren(component.root);
component.root.checkCanonicalNameChildren();
}
}
void _checkCanonicalNameChildren(CanonicalName parent) {
Iterable<CanonicalName>? parentChildren = parent.childrenOrNull;
if (parentChildren != null) {
for (CanonicalName child in parentChildren) {
if (child.name != '@methods' &&
child.name != '@typedefs' &&
child.name != '@getters' &&
child.name != '@setters' &&
child.name != '@factories' &&
child.name != '@constructors') {
bool checkReferenceNode = true;
if (child.reference == null) {
// OK for "if private: URI of library" part of "Qualified name"...
// TODO(johnniwinther): This wrongfully skips checking of variable
// synthesized by the VM transformations. The kind of canonical
// name types maybe should be directly available.
if (parent.parent != null && child.name.contains(':')) {
// OK then.
checkReferenceNode = false;
} else {
throw buildCanonicalNameError(
"Null reference (${child.name}) ($child).", child);
}
}
if (checkReferenceNode) {
if (child.reference!.canonicalName != child) {
throw new CanonicalNameError(
"Canonical name and reference doesn't agree.");
}
if (child.reference!.node == null) {
throw buildCanonicalNameError(
"Reference is null (${child.name}) ($child).", child);
}
}
}
_checkCanonicalNameChildren(child);
}
}
}
CanonicalNameError buildCanonicalNameError(
String message, CanonicalName problemNode) {
// Special-case missing sdk entries as that is probably a change to the
// platform - that's something we might want to react differently to.
String libraryUri = problemNode.nonRootTop?.name ?? "";
if (libraryUri.startsWith("dart:")) {
return new CanonicalNameSdkError(message);
}
return new CanonicalNameError(message);
}
_ComponentIndex _readComponentIndex(int componentFileSize) {
int savedByteIndex = _byteOffset;
@ -1057,12 +990,12 @@ class BinaryBuilder {
Reference? readNullableLibraryReference() {
CanonicalName? canonicalName = readNullableCanonicalNameReference();
return canonicalName?.getReference();
return canonicalName?.reference;
}
Reference readNonNullLibraryReference() {
CanonicalName? canonicalName = readNullableCanonicalNameReference();
if (canonicalName != null) return canonicalName.getReference();
if (canonicalName != null) return canonicalName.reference;
throw 'Expected a library reference to be valid but was `null`.';
}
@ -1073,7 +1006,7 @@ class BinaryBuilder {
Reference? readNullableClassReference() {
CanonicalName? name = readNullableCanonicalNameReference();
return name?.getReference();
return name?.reference;
}
Reference readNonNullClassReference() {
@ -1081,7 +1014,7 @@ class BinaryBuilder {
if (name == null) {
throw 'Expected a class reference to be valid but was `null`.';
}
return name.getReference();
return name.reference;
}
void skipMemberReference() {
@ -1090,7 +1023,7 @@ class BinaryBuilder {
Reference? readNullableMemberReference() {
CanonicalName? name = readNullableCanonicalNameReference();
return name?.getReference();
return name?.reference;
}
Reference readNonNullMemberReference() {
@ -1098,7 +1031,7 @@ class BinaryBuilder {
if (name == null) {
throw 'Expected a member reference to be valid but was `null`.';
}
return name.getReference();
return name.reference;
}
Reference? readNullableInstanceMemberReference() {
@ -1114,15 +1047,15 @@ class BinaryBuilder {
}
Reference? getNullableMemberReferenceFromInt(int index) {
return getNullableCanonicalNameReferenceFromInt(index)?.getReference();
return getNullableCanonicalNameReferenceFromInt(index)?.reference;
}
Reference? readNullableTypedefReference() {
return readNullableCanonicalNameReference()?.getReference();
return readNullableCanonicalNameReference()?.reference;
}
Reference readNonNullTypedefReference() {
return readNonNullCanonicalNameReference().getReference();
return readNonNullCanonicalNameReference().reference;
}
Name readName() {
@ -1175,7 +1108,7 @@ class BinaryBuilder {
int languageVersionMinor = readUInt30();
CanonicalName canonicalName = readNonNullCanonicalNameReference();
Reference reference = canonicalName.getReference();
Reference reference = canonicalName.reference;
Library? library = reference.node as Library?;
if (alwaysCreateNewNamedNodes) {
library = null;
@ -1268,7 +1201,7 @@ class BinaryBuilder {
library.additionalExports.clear();
for (int i = 0; i < numExportedReference; i++) {
CanonicalName exportedName = readNonNullCanonicalNameReference();
Reference reference = exportedName.getReference();
Reference reference = exportedName.reference;
library.additionalExports.add(reference);
}
}
@ -1307,7 +1240,7 @@ class BinaryBuilder {
Typedef readTypedef() {
CanonicalName canonicalName = readNonNullCanonicalNameReference();
Reference reference = canonicalName.getReference();
Reference reference = canonicalName.reference;
Typedef? node = reference.node as Typedef?;
if (alwaysCreateNewNamedNodes) {
node = null;
@ -1355,7 +1288,7 @@ class BinaryBuilder {
_byteOffset = savedByteOffset;
CanonicalName canonicalName = readNonNullCanonicalNameReference();
Reference reference = canonicalName.getReference();
Reference reference = canonicalName.reference;
Class? node = reference.node as Class?;
if (alwaysCreateNewNamedNodes) {
node = null;
@ -1411,7 +1344,7 @@ class BinaryBuilder {
assert(tag == Tag.Extension);
CanonicalName canonicalName = readNonNullCanonicalNameReference();
Reference reference = canonicalName.getReference();
Reference reference = canonicalName.reference;
Extension? node = reference.node as Extension?;
if (alwaysCreateNewNamedNodes) {
node = null;
@ -1447,7 +1380,7 @@ class BinaryBuilder {
node.members[i] = new ExtensionMemberDescriptor(
name: name,
kind: ExtensionMemberKind.values[kind],
member: canonicalName.getReference())
member: canonicalName.reference)
..flags = flags;
}
return node;
@ -1501,9 +1434,9 @@ class BinaryBuilder {
int tag = readByte();
assert(tag == Tag.Field);
CanonicalName getterCanonicalName = readNonNullCanonicalNameReference();
Reference getterReference = getterCanonicalName.getReference();
Reference getterReference = getterCanonicalName.reference;
CanonicalName? setterCanonicalName = readNullableCanonicalNameReference();
Reference? setterReference = setterCanonicalName?.getReference();
Reference? setterReference = setterCanonicalName?.reference;
Field? node = getterReference.node as Field?;
if (alwaysCreateNewNamedNodes) {
node = null;
@ -1547,7 +1480,7 @@ class BinaryBuilder {
int tag = readByte();
assert(tag == Tag.Constructor);
CanonicalName canonicalName = readNonNullCanonicalNameReference();
Reference reference = canonicalName.getReference();
Reference reference = canonicalName.reference;
Constructor? node = reference.node as Constructor?;
if (alwaysCreateNewNamedNodes) {
node = null;
@ -1589,7 +1522,7 @@ class BinaryBuilder {
int tag = readByte();
assert(tag == Tag.Procedure);
CanonicalName canonicalName = readNonNullCanonicalNameReference();
Reference reference = canonicalName.getReference();
Reference reference = canonicalName.reference;
Procedure? node = reference.node as Procedure?;
if (alwaysCreateNewNamedNodes) {
node = null;
@ -1648,7 +1581,7 @@ class BinaryBuilder {
int tag = readByte();
assert(tag == Tag.RedirectingFactoryConstructor);
CanonicalName canonicalName = readNonNullCanonicalNameReference();
Reference reference = canonicalName.getReference();
Reference reference = canonicalName.reference;
RedirectingFactoryConstructor? node =
reference.node as RedirectingFactoryConstructor?;
if (alwaysCreateNewNamedNodes) {
@ -2354,8 +2287,7 @@ class BinaryBuilder {
int fieldValueCount = readUInt30();
Map<Reference, Expression> fieldValues = <Reference, Expression>{};
for (int i = 0; i < fieldValueCount; i++) {
final Reference fieldRef =
readNonNullCanonicalNameReference().getReference();
final Reference fieldRef = readNonNullCanonicalNameReference().reference;
final Expression value = readExpression();
fieldValues[fieldRef] = value;
}

View file

@ -251,7 +251,8 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
}
} else if (constant is TearOffConstant) {
writeByte(ConstantTag.TearOffConstant);
writeNonNullCanonicalNameReference(constant.procedure.canonicalName!);
writeNonNullCanonicalNameReference(
constant.procedure.reference.canonicalName!);
} else if (constant is TypeLiteralConstant) {
writeByte(ConstantTag.TypeLiteralConstant);
writeDartType(constant.type);
@ -503,8 +504,8 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
for (int i = 0; i < component.libraries.length; ++i) {
Library library = component.libraries[i];
if (libraryFilter == null || libraryFilter!(library)) {
_indexLinkTableInternal(library.canonicalName!);
_knownCanonicalNameNonRootTops.add(library.canonicalName!);
_indexLinkTableInternal(library.reference.canonicalName!);
_knownCanonicalNameNonRootTops.add(library.reference.canonicalName!);
}
}
}
@ -940,11 +941,11 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
}
void writeLibraryReference(Library node, {bool allowNull: false}) {
if (node.canonicalName == null && !allowNull) {
if (node.reference.canonicalName == null && !allowNull) {
throw new ArgumentError(
'Expected a library reference to be valid but was `null`.');
}
writeNullAllowedCanonicalNameReference(node.canonicalName);
writeNullAllowedCanonicalNameReference(node.reference.canonicalName);
}
writeOffset(int offset) {
@ -1149,7 +1150,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
if (node.isAnonymousMixin) _currentlyInNonimplementation = true;
if (node.canonicalName == null) {
if (node.reference.canonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
writeByte(Tag.Class);
@ -1192,7 +1193,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
@override
void visitConstructor(Constructor node) {
if (node.canonicalName == null) {
if (node.reference.canonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
enterScope(memberScope: true);
@ -1233,24 +1234,23 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
procedureOffsets.add(getBufferOffset());
if (node.canonicalName == null) {
CanonicalName? canonicalName = node.reference.canonicalName;
if (canonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
if (node.reference.node != node) {
String? orphancy = node.reference.getOrphancyDescription(node);
if (orphancy != null) {
throw new ArgumentError(
'Trying to serialize orphaned procedure reference.\n'
'Orphaned procedure ${node} (${node.runtimeType}:${node.hashCode})\n'
'Linked node ${node.reference.node} '
'(${node.reference.node.runtimeType}:'
'${node.reference.node.hashCode})');
'${orphancy}');
}
if (node.canonicalName!.reference?.node != node) {
orphancy = canonicalName.getOrphancyDescription(node, node.reference);
if (orphancy != null) {
throw new ArgumentError(
'Trying to serialize orphaned procedure canonical name.\n'
'Orphaned procedure ${node} (${node.runtimeType}:${node.hashCode})\n'
'Linked node ${node.canonicalName!.reference?.node} '
'(${node.canonicalName!.reference?.node.runtimeType}:'
'${node.canonicalName!.reference?.node.hashCode})');
'${orphancy}');
}
final bool currentlyInNonimplementationSaved =
@ -1284,54 +1284,49 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
@override
void visitField(Field node) {
if (node.getterCanonicalName == null) {
CanonicalName? getterCanonicalName = node.getterReference.canonicalName;
if (getterCanonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
if (node.getterReference.node != node) {
String? getterOrphancy = node.getterReference.getOrphancyDescription(node);
if (getterOrphancy != null) {
throw new ArgumentError('Trying to serialize orphaned getter reference.\n'
'Orphaned getter ${node} (${node.runtimeType}:${node.hashCode})\n'
'Linked node ${node.getterReference.node} '
'(${node.getterReference.node.runtimeType}:'
'${node.getterReference.node.hashCode})');
'${getterOrphancy}');
}
if (node.getterCanonicalName!.reference?.node != node) {
getterOrphancy =
getterCanonicalName.getOrphancyDescription(node, node.getterReference);
if (getterOrphancy != null) {
throw new ArgumentError(
'Trying to serialize orphaned getter canonical name.\n'
'Orphaned getter ${node} '
'(${node.runtimeType}:${node.hashCode})\n'
'Linked node ${node.getterCanonicalName!.reference?.node} '
'(${node.getterCanonicalName!.reference?.node.runtimeType}:'
'${node.getterCanonicalName!.reference?.node.hashCode})');
'${getterOrphancy}');
}
CanonicalName? setterCanonicalName;
if (node.hasSetter) {
if (node.setterCanonicalName == null) {
Reference setterReference = node.setterReference!;
setterCanonicalName = setterReference.canonicalName;
if (setterCanonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
if (node.setterReference?.node != node) {
String? setterOrphancy = setterReference.getOrphancyDescription(node);
if (setterOrphancy != null) {
throw new ArgumentError(
'Trying to serialize orphaned setter reference.\n'
'Orphaned setter ${node} (${node.runtimeType}:${node.hashCode})\n'
'Linked node ${node.setterReference?.node}'
'(${node.setterReference?.node.runtimeType}:'
'${node.setterReference?.node.hashCode})');
'${setterOrphancy}');
}
if (node.setterCanonicalName!.reference?.node != node) {
setterOrphancy =
setterCanonicalName.getOrphancyDescription(node, setterReference);
if (setterOrphancy != null) {
throw new ArgumentError(
'Trying to serialize orphaned setter canonical name.\n'
'Orphaned setter ${node} (${node.runtimeType}:${node.hashCode})\n'
'Linked node ${node.setterCanonicalName!.reference?.node} '
'(${node.setterCanonicalName!.reference?.node.runtimeType}:'
'${node.setterCanonicalName!.reference?.node.hashCode})');
'${setterOrphancy}');
}
}
enterScope(memberScope: true);
writeByte(Tag.Field);
writeNonNullCanonicalNameReference(getCanonicalNameOfMemberGetter(node));
if (node.hasSetter) {
writeNonNullCanonicalNameReference(getCanonicalNameOfMemberSetter(node));
} else {
writeNullAllowedReference(null);
}
writeNonNullCanonicalNameReference(getterCanonicalName);
writeNullAllowedCanonicalNameReference(setterCanonicalName);
writeUriReference(node.fileUri);
writeOffset(node.fileOffset);
writeOffset(node.fileEndOffset);
@ -1345,7 +1340,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
@override
void visitRedirectingFactoryConstructor(RedirectingFactoryConstructor node) {
if (node.canonicalName == null) {
if (node.reference.canonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
writeByte(Tag.RedirectingFactoryConstructor);
@ -2413,7 +2408,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
@override
void visitExtension(Extension node) {
if (node.canonicalName == null) {
if (node.reference.canonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
writeByte(Tag.Extension);

View file

@ -82,7 +82,7 @@ class CanonicalName {
Map<String, CanonicalName>? _children;
/// The library, class, or member bound to this name.
Reference? reference;
Reference? _reference;
/// Temporary index used during serialization.
int index = -1;
@ -205,8 +205,8 @@ class CanonicalName {
if (target == null) {
throw '$this cannot be bound to null';
}
if (reference == target) return;
if (reference != null) {
if (_reference == target) return;
if (_reference != null) {
throw '$this is already bound';
}
if (target.canonicalName != null) {
@ -214,7 +214,7 @@ class CanonicalName {
'${target.canonicalName}';
}
target.canonicalName = this;
this.reference = target;
this._reference = target;
}
void unbind() {
@ -228,16 +228,16 @@ class CanonicalName {
}
void _unbindInternal() {
if (reference == null) return;
assert(reference!.canonicalName == this);
if (reference!.node is Class) {
if (_reference == null) return;
assert(_reference!.canonicalName == this);
if (_reference!.node is Class) {
// TODO(jensj): Get rid of this. This is only needed because pkg:vm does
// weird stuff in transformations. `unbind` should probably be private.
Class c = reference!.asClass;
Class c = _reference!.asClass;
c.ensureLoaded();
}
reference!.canonicalName = null;
reference = null;
_reference!.canonicalName = null;
_reference = null;
}
void unbindAll() {
@ -257,12 +257,55 @@ class CanonicalName {
return "${parent!.toStringInternal()}::$name";
}
Reference getReference() {
return reference ??= (new Reference()..canonicalName = this);
Reference get reference {
return _reference ??= (new Reference()..canonicalName = this);
}
void checkCanonicalNameChildren() {
CanonicalName parent = this;
Iterable<CanonicalName>? parentChildren = parent.childrenOrNull;
if (parentChildren != null) {
for (CanonicalName child in parentChildren) {
if (child.name != '@methods' &&
child.name != '@typedefs' &&
child.name != '@fields' &&
child.name != '@=fields' &&
child.name != '@getters' &&
child.name != '@setters' &&
child.name != '@factories' &&
child.name != '@constructors') {
bool checkReferenceNode = true;
if (child._reference == null) {
// OK for "if private: URI of library" part of "Qualified name"...
// TODO(johnniwinther): This wrongfully skips checking of variable
// synthesized by the VM transformations. The kind of canonical
// name types maybe should be directly available.
if (parent.parent != null && child.name.contains(':')) {
// OK then.
checkReferenceNode = false;
} else {
throw buildCanonicalNameError(
"Null reference (${child.name}) ($child).", child);
}
}
if (checkReferenceNode) {
if (child._reference!.canonicalName != child) {
throw buildCanonicalNameError(
"Canonical name and reference doesn't agree.", child);
}
if (child._reference!.node == null) {
throw buildCanonicalNameError(
"Reference is null (${child.name}) ($child).", child);
}
}
}
child.checkCanonicalNameChildren();
}
}
}
bool get isConsistent {
if (reference != null && !reference!.isConsistent) {
if (_reference != null && !_reference!.isConsistent) {
return false;
}
return true;
@ -271,8 +314,8 @@ class CanonicalName {
String getInconsistency() {
StringBuffer sb = new StringBuffer();
sb.write('CanonicalName ${this} (${hashCode}):');
if (reference != null) {
sb.write(' ${reference!.getInconsistency()}');
if (_reference != null) {
sb.write(' ${_reference!.getInconsistency()}');
}
return sb.toString();
}
@ -283,4 +326,252 @@ class CanonicalName {
if (procedure.isFactory) return '@factories';
return '@methods';
}
/// Returns `true` if [node] is orphaned through its [reference].
///
/// A [NamedNode] is orphaned if the canonical name of its reference doesn't
/// point back to the node itself. This can occur if the [reference] is
/// repurposed for a new [NamedNode]. In this case, the reference will be
/// updated to point the new node.
///
/// This method assumes that `reference.canonicalName` is this canonical name.
bool isOrphaned(NamedNode node, Reference reference) {
assert(reference.canonicalName == this);
return _reference?._node != node;
}
/// Returns a description of the orphancy, if [node] is orphaned through its
/// [reference]. Otherwise `null`.
///
/// A [NamedNode] is orphaned if the canonical name of its reference doesn't
/// point back to the node itself. This can occur if the [reference] is
/// repurposed for a new [NamedNode]. In this case, the reference will be
/// updated to point the new node.
///
/// This method assumes that `reference.canonicalName` is this canonical name.
String? getOrphancyDescription(NamedNode node, Reference reference) {
assert(reference.canonicalName == this);
if (_reference?._node != node) {
return _reference!.getOrphancyDescription(node);
}
return null;
}
}
/// Indirection between a reference and its definition.
///
/// There is only one reference object per [NamedNode].
class Reference {
CanonicalName? canonicalName;
NamedNode? _node;
NamedNode? get node {
if (_node == null) {
// Either this is an unbound reference or it belongs to a lazy-loaded
// (and not yet loaded) class. If it belongs to a lazy-loaded class,
// load the class.
CanonicalName? canonicalNameParent = canonicalName?.parent;
while (canonicalNameParent != null) {
if (canonicalNameParent.name.startsWith("@")) {
break;
}
canonicalNameParent = canonicalNameParent.parent;
}
if (canonicalNameParent != null) {
NamedNode? parentNamedNode =
canonicalNameParent.parent?.reference._node;
if (parentNamedNode is Class) {
Class parentClass = parentNamedNode;
if (parentClass.lazyBuilder != null) {
parentClass.ensureLoaded();
}
}
}
}
return _node;
}
void set node(NamedNode? node) {
_node = node;
}
String toString() {
return "Reference to ${toStringInternal()}";
}
String toStringInternal() {
if (canonicalName != null) {
return '${canonicalName!.toStringInternal()}';
}
if (node != null) {
return node!.toStringInternal();
}
return 'Unbound reference';
}
Library get asLibrary {
if (node == null) {
throw '$this is not bound to an AST node. A library was expected';
}
return node as Library;
}
Class get asClass {
if (node == null) {
throw '$this is not bound to an AST node. A class was expected';
}
return node as Class;
}
Member get asMember {
if (node == null) {
throw '$this is not bound to an AST node. A member was expected';
}
return node as Member;
}
Field get asField {
if (node == null) {
throw '$this is not bound to an AST node. A field was expected';
}
return node as Field;
}
Constructor get asConstructor {
if (node == null) {
throw '$this is not bound to an AST node. A constructor was expected';
}
return node as Constructor;
}
Procedure get asProcedure {
if (node == null) {
throw '$this is not bound to an AST node. A procedure was expected';
}
return node as Procedure;
}
Typedef get asTypedef {
if (node == null) {
throw '$this is not bound to an AST node. A typedef was expected';
}
return node as Typedef;
}
Extension get asExtension {
if (node == null) {
throw '$this is not bound to an AST node. An extension was expected';
}
return node as Extension;
}
bool get isConsistent {
NamedNode? node = _node;
if (node != null) {
if (node.reference != this &&
(node is! Field || node.setterReference != this)) {
// The reference of a [NamedNode] must point to this reference, or
// if the node is a [Field] the setter reference must point to this
// reference.
return false;
}
}
if (canonicalName != null && canonicalName!._reference != this) {
return false;
}
return true;
}
String getInconsistency() {
StringBuffer sb = new StringBuffer();
sb.write('Reference ${this} (${hashCode}):');
NamedNode? node = _node;
if (node != null) {
if (node is Field) {
if (node.getterReference != this && node.setterReference != this) {
sb.write(' _node=${node} (${node.runtimeType}:${node.hashCode})');
sb.write(' _node.getterReference='
'${node.getterReference} (${node.getterReference.hashCode})');
sb.write(' _node.setterReference='
'${node.setterReference} (${node.setterReference.hashCode})');
}
} else {
if (node.reference != this) {
sb.write(' _node=${node} (${node.runtimeType}:${node.hashCode})');
sb.write(' _node.reference='
'${node.reference} (${node.reference.hashCode})');
}
}
}
if (canonicalName != null && canonicalName!._reference != this) {
sb.write(' canonicalName=${canonicalName} (${canonicalName.hashCode})');
sb.write(' canonicalName.reference='
'${canonicalName!._reference} '
'(${canonicalName!._reference.hashCode})');
}
return sb.toString();
}
/// Returns `true` if [node] is orphaned through this reference.
///
/// A [NamedNode] is orphaned if its reference doesn't point back to the node
/// itself. This can occur if the [reference] is repurposed for a new
/// [NamedNode]. In this case, the reference will be updated to point the new
/// node.
///
/// This method assumes that this reference is the reference, possibly
/// getter or setter reference for a field, of [node].
bool isOrphaned(NamedNode node) {
return _node != node;
}
/// Returns a description of the orphancy, if [node] is orphaned through this
/// reference. Otherwise `null`.
///
/// A [NamedNode] is orphaned if its reference doesn't point back to the node
/// itself. This can occur if the [reference] is repurposed for a new
/// [NamedNode]. In this case, the reference will be updated to point the new
/// node.
///
/// This method assumes that this reference is the reference, possibly
/// getter or setter reference for a field, of [node].
String? getOrphancyDescription(NamedNode node) {
if (_node != node) {
StringBuffer sb = new StringBuffer();
sb.write('Orphaned named node ${node} ');
sb.write('(${node.runtimeType}:${node.hashCode})\n');
sb.write('Linked node ${_node} ');
sb.write('(${_node.runtimeType}:');
sb.write('${_node.hashCode})');
return sb.toString();
}
return null;
}
}
class CanonicalNameError {
final String message;
CanonicalNameError(this.message);
String toString() => 'CanonicalNameError: $message';
}
class CanonicalNameSdkError extends CanonicalNameError {
CanonicalNameSdkError(String message) : super(message);
String toString() => 'CanonicalNameSdkError: $message';
}
CanonicalNameError buildCanonicalNameError(
String message, CanonicalName problemNode) {
// Special-case missing sdk entries as that is probably a change to the
// platform - that's something we might want to react differently to.
String libraryUri = problemNode.nonRootTop?.name ?? "";
if (libraryUri.startsWith("dart:")) {
return new CanonicalNameSdkError(message);
}
return new CanonicalNameError(message);
}

View file

@ -1016,8 +1016,8 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
if (name.name.startsWith('@')) throw 'unexpected @';
String libraryString(CanonicalName lib) {
if (lib.reference?.node != null) {
return getLibraryReference(lib.reference!.asLibrary);
if (lib.reference.node != null) {
return getLibraryReference(lib.reference.asLibrary);
}
return syntheticNames.nameCanonicalNameAsLibraryPrefix(
lib.reference, lib);

View file

@ -24,8 +24,8 @@ TextSerializer<Name> publicName =
Wrapped<String, Name>((w) => w.text, (u) => Name(u), const DartString());
TextSerializer<Name> privateName = Wrapped<Tuple2<String, CanonicalName>, Name>(
(w) => Tuple2(w.text, w.library!.canonicalName!),
(u) => Name.byReference(u.first, u.second.getReference()),
(w) => Tuple2(w.text, w.library!.reference.canonicalName!),
(u) => Name.byReference(u.first, u.second.reference),
Tuple2Serializer(DartString(), CanonicalNameSerializer()));
TextSerializer<Name> nameSerializer = new Case(
@ -464,7 +464,7 @@ InstanceGet wrapInstanceGet(
Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
tuple) {
return new InstanceGet.byReference(tuple.first, tuple.second, tuple.third,
interfaceTargetReference: tuple.fourth.getReference(),
interfaceTargetReference: tuple.fourth.reference,
resultType: tuple.fifth);
}
@ -487,7 +487,7 @@ InstanceSet wrapInstanceSet(
tuple) {
return new InstanceSet.byReference(
tuple.first, tuple.second, tuple.third, tuple.fourth,
interfaceTargetReference: tuple.fifth.getReference());
interfaceTargetReference: tuple.fifth.reference);
}
TextSerializer<DynamicGet> dynamicGetSerializer =
@ -546,7 +546,7 @@ InstanceTearOff wrapInstanceTearOff(
Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
tuple) {
return new InstanceTearOff.byReference(tuple.first, tuple.second, tuple.third,
interfaceTargetReference: tuple.fourth.getReference(),
interfaceTargetReference: tuple.fourth.reference,
resultType: tuple.fifth);
}
@ -652,7 +652,7 @@ InstanceInvocation wrapInstanceInvocation(
tuple) {
return new InstanceInvocation.byReference(
tuple.first, tuple.second, tuple.third, tuple.fourth,
interfaceTargetReference: tuple.fifth.getReference(),
interfaceTargetReference: tuple.fifth.reference,
functionType: tuple.sixth as FunctionType);
}
@ -785,7 +785,7 @@ Tuple4<Expression, Expression, CanonicalName, DartType> unwrapEqualsCall(
EqualsCall wrapEqualsCall(
Tuple4<Expression, Expression, CanonicalName, DartType> tuple) {
return new EqualsCall.byReference(tuple.first, tuple.second,
interfaceTargetReference: tuple.third.getReference(),
interfaceTargetReference: tuple.third.reference,
functionType: tuple.fourth as FunctionType);
}
@ -880,7 +880,7 @@ CanonicalName unwrapStaticGet(StaticGet expression) {
}
StaticGet wrapStaticGet(CanonicalName name) {
return new StaticGet.byReference(name.getReference());
return new StaticGet.byReference(name.reference);
}
const TextSerializer<StaticTearOff> staticTearOffSerializer = const Wrapped(
@ -891,7 +891,7 @@ CanonicalName unwrapStaticTearOff(StaticTearOff expression) {
}
StaticTearOff wrapStaticTearOff(CanonicalName name) {
return new StaticTearOff.byReference(name.getReference());
return new StaticTearOff.byReference(name.reference);
}
TextSerializer<StaticSet> staticSetSerializer = new Wrapped(
@ -905,7 +905,7 @@ Tuple2<CanonicalName, Expression> unwrapStaticSet(StaticSet expression) {
}
StaticSet wrapStaticSet(Tuple2<CanonicalName, Expression> tuple) {
return new StaticSet.byReference(tuple.first.getReference(), tuple.second);
return new StaticSet.byReference(tuple.first.reference, tuple.second);
}
TextSerializer<StaticInvocation> staticInvocationSerializer = new Wrapped(
@ -920,8 +920,7 @@ Tuple2<CanonicalName, Arguments> unwrapStaticInvocation(
}
StaticInvocation wrapStaticInvocation(Tuple2<CanonicalName, Arguments> tuple) {
return new StaticInvocation.byReference(
tuple.first.getReference(), tuple.second,
return new StaticInvocation.byReference(tuple.first.reference, tuple.second,
isConst: false);
}
@ -932,8 +931,7 @@ TextSerializer<StaticInvocation> constStaticInvocationSerializer = new Wrapped(
StaticInvocation wrapConstStaticInvocation(
Tuple2<CanonicalName, Arguments> tuple) {
return new StaticInvocation.byReference(
tuple.first.getReference(), tuple.second,
return new StaticInvocation.byReference(tuple.first.reference, tuple.second,
isConst: true);
}
@ -950,7 +948,7 @@ Tuple2<CanonicalName, Arguments> unwrapConstructorInvocation(
ConstructorInvocation wrapConstructorInvocation(
Tuple2<CanonicalName, Arguments> tuple) {
return new ConstructorInvocation.byReference(
tuple.first.getReference(), tuple.second,
tuple.first.reference, tuple.second,
isConst: false);
}
@ -961,7 +959,7 @@ TextSerializer<ConstructorInvocation> constConstructorInvocationSerializer =
ConstructorInvocation wrapConstConstructorInvocation(
Tuple2<CanonicalName, Arguments> tuple) {
return new ConstructorInvocation.byReference(
tuple.first.getReference(), tuple.second,
tuple.first.reference, tuple.second,
isConst: true);
}
@ -1045,9 +1043,9 @@ TextSerializer<InstanceCreation> instanceCreationSerializer = Wrapped<
ic.asserts,
ic.unusedArguments),
(t) => InstanceCreation(
t.first.getReference(),
t.first.reference,
t.second,
Map.fromIterables(t.third.map((cn) => cn.getReference()), t.fourth),
Map.fromIterables(t.third.map((cn) => cn.reference), t.fourth),
t.fifth,
t.sixth),
Tuple6Serializer(
@ -1301,7 +1299,7 @@ Tuple2<CanonicalName, List<DartType>> unwrapInterfaceType(InterfaceType node) {
InterfaceType wrapInterfaceType(Tuple2<CanonicalName, List<DartType>> tuple) {
return new InterfaceType.byReference(
tuple.first.getReference(), Nullability.legacy, tuple.second);
tuple.first.reference, Nullability.legacy, tuple.second);
}
TextSerializer<TypedefType> typedefTypeSerializer = new Wrapped(
@ -1316,7 +1314,7 @@ Tuple2<CanonicalName, List<DartType>> unwrapTypedefType(TypedefType node) {
TypedefType wrapTypedefType(Tuple2<CanonicalName, List<DartType>> tuple) {
return new TypedefType.byReference(
tuple.first.reference!, Nullability.legacy, tuple.second);
tuple.first.reference, Nullability.legacy, tuple.second);
}
TextSerializer<FutureOrType> futureOrTypeSerializer =
@ -2133,7 +2131,7 @@ TextSerializer<LibraryDependency> libraryDependencySerializer = Wrapped<
(ld) => Tuple5(ld.importedLibraryReference.canonicalName!, ld.name,
ld.combinators, ld.flags, ld.annotations),
(t) => LibraryDependency.byReference(
t.fourth, t.fifth, t.first.getReference(), t.second, t.third),
t.fourth, t.fifth, t.first.reference, t.second, t.third),
Tuple5Serializer(
CanonicalNameSerializer(),
Optional(DartString()),
@ -2227,13 +2225,13 @@ TextSerializer<StringConstant> stringConstantSerializer =
TextSerializer<SymbolConstant> symbolConstantSerializer =
Wrapped<Tuple2<String, CanonicalName?>, SymbolConstant>(
(w) => Tuple2(w.name, w.libraryReference?.canonicalName),
(u) => SymbolConstant(u.first, u.second?.getReference()),
(u) => SymbolConstant(u.first, u.second?.reference),
Tuple2Serializer(DartString(), Optional(CanonicalNameSerializer())));
TextSerializer<TearOffConstant> tearOffConstantSerializer =
Wrapped<CanonicalName, TearOffConstant>(
(w) => w.procedureReference.canonicalName!,
(u) => TearOffConstant.byReference(u.getReference()),
(u) => TearOffConstant.byReference(u.reference),
CanonicalNameSerializer());
TextSerializer<TypeLiteralConstant> typeLiteralConstantSerializer =
@ -2254,8 +2252,8 @@ TextSerializer<InstanceConstant> instanceConstantSerializer =
w.typeArguments,
w.fieldValues.keys.map((r) => r.canonicalName!).toList(),
w.fieldValues.values.toList()),
(u) => InstanceConstant(u.first.getReference(), u.second,
Map.fromIterables(u.third.map((c) => c.getReference()), u.fourth)),
(u) => InstanceConstant(u.first.reference, u.second,
Map.fromIterables(u.third.map((c) => c.reference), u.fourth)),
Tuple4Serializer(
CanonicalNameSerializer(),
ListSerializer(dartTypeSerializer),
@ -2293,7 +2291,7 @@ TextSerializer<AssertInitializer> assertInitializerSerializer =
TextSerializer<FieldInitializer> fieldInitializerSerializer =
Wrapped<Tuple2<CanonicalName, Expression>, FieldInitializer>(
(w) => Tuple2(w.fieldReference.canonicalName!, w.value),
(u) => FieldInitializer.byReference(u.first.getReference(), u.second),
(u) => FieldInitializer.byReference(u.first.reference, u.second),
Tuple2Serializer(CanonicalNameSerializer(), expressionSerializer));
TextSerializer<InvalidInitializer> invalidInitializerSerializer =
@ -2307,14 +2305,13 @@ TextSerializer<LocalInitializer> localInitializerSerializer =
TextSerializer<RedirectingInitializer> redirectingInitializerSerializer =
Wrapped<Tuple2<CanonicalName, Arguments>, RedirectingInitializer>(
(w) => Tuple2(w.targetReference.canonicalName!, w.arguments),
(u) => RedirectingInitializer.byReference(
u.first.getReference(), u.second),
(u) => RedirectingInitializer.byReference(u.first.reference, u.second),
Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
TextSerializer<SuperInitializer> superInitializerSerializer =
Wrapped<Tuple2<CanonicalName, Arguments>, SuperInitializer>(
(w) => Tuple2(w.targetReference.canonicalName!, w.arguments),
(u) => SuperInitializer.byReference(u.first.getReference(), u.second),
(u) => SuperInitializer.byReference(u.first.reference, u.second),
Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
Case<Initializer> initializerSerializer =
@ -2323,7 +2320,7 @@ Case<Initializer> initializerSerializer =
TextSerializer<Supertype> supertypeSerializer =
Wrapped<Tuple2<CanonicalName, List<DartType>>, Supertype>(
(w) => Tuple2(w.className.canonicalName!, w.typeArguments),
(u) => Supertype.byReference(u.first.getReference(), u.second),
(u) => Supertype.byReference(u.first.reference, u.second),
Tuple2Serializer(
CanonicalNameSerializer(), ListSerializer(dartTypeSerializer)));
@ -2453,7 +2450,7 @@ TextSerializer<ExtensionMemberDescriptor> extensionMemberDescriptorSerializer =
ExtensionMemberDescriptor>(
(w) => Tuple4(w.name, w.kind, w.flags, w.member.canonicalName!),
(u) => ExtensionMemberDescriptor(
name: u.first, kind: u.second, member: u.fourth.getReference())
name: u.first, kind: u.second, member: u.fourth.reference)
..flags = u.third,
Tuple4Serializer(
nameSerializer,

View file

@ -37,15 +37,15 @@ main() {
List<int> writtenBytesFieldOriginal = serialize(lib1, lib2);
// Canonical names are now set: Verify that the field is marked as such,
// canonical-name-wise.
String getterCanonicalName = '${field.getterCanonicalName}';
if (field.getterCanonicalName.parent.name != "@getters") {
String getterCanonicalName = '${field.getterReference.canonicalName}';
if (field.getterReference.canonicalName.parent.name != "@getters") {
throw "Expected @getters parent, but had "
"${field.getterCanonicalName.parent.name}";
"${field.getterReference.canonicalName.parent.name}";
}
String setterCanonicalName = '${field.setterCanonicalName}';
if (field.setterCanonicalName.parent.name != "@setters") {
String setterCanonicalName = '${field.setterReference.canonicalName}';
if (field.setterReference.canonicalName.parent.name != "@setters") {
throw "Expected @setters parent, but had "
"${field.setterCanonicalName.parent.name}";
"${field.setterReference.canonicalName.parent.name}";
}
// Replace the field with a setter/getter pair.
@ -78,21 +78,23 @@ main() {
List<int> writtenBytesGetterSetter = serialize(lib1, lib2);
// Canonical names are now set: Verify that the getter/setter is marked as
// such, canonical-name-wise.
if (getter.canonicalName.parent.name != "@getters") {
if (getter.reference.canonicalName.parent.name != "@getters") {
throw "Expected @getters parent, but had "
"${getter.canonicalName.parent.name}";
"${getter.reference.canonicalName.parent.name}";
}
if ('${getter.canonicalName}' != getterCanonicalName) {
if ('${getter.reference.canonicalName}' != getterCanonicalName) {
throw "Unexpected getter canonical name. "
"Expected $getterCanonicalName, actual ${getter.canonicalName}.";
"Expected $getterCanonicalName, "
"actual ${getter.reference.canonicalName}.";
}
if (setter.canonicalName.parent.name != "@setters") {
if (setter.reference.canonicalName.parent.name != "@setters") {
throw "Expected @setters parent, but had "
"${setter.canonicalName.parent.name}";
"${setter.reference.canonicalName.parent.name}";
}
if ('${setter.canonicalName}' != setterCanonicalName) {
if ('${setter.reference.canonicalName}' != setterCanonicalName) {
throw "Unexpected setter canonical name. "
"Expected $setterCanonicalName, actual ${setter.canonicalName}.";
"Expected $setterCanonicalName, "
"actual ${setter.reference.canonicalName}.";
}
// Replace getter/setter with field.
@ -111,13 +113,15 @@ main() {
List<int> writtenBytesFieldNew = serialize(lib1, lib2);
// Canonical names are now set: Verify that the field is marked as such,
// canonical-name-wise.
if (fieldReplacement.getterCanonicalName.parent.name != "@getters") {
if (fieldReplacement.getterReference.canonicalName.parent.name !=
"@getters") {
throw "Expected @getters parent, but had "
"${fieldReplacement.getterCanonicalName.parent.name}";
"${fieldReplacement.getterReference.canonicalName.parent.name}";
}
if (fieldReplacement.setterCanonicalName.parent.name != "@setters") {
if (fieldReplacement.setterReference.canonicalName.parent.name !=
"@setters") {
throw "Expected @setters parent, but had "
"${fieldReplacement.setterCanonicalName.parent.name}";
"${fieldReplacement.setterReference.canonicalName.parent.name}";
}
// Load the written stuff and ensure it is as expected.

View file

@ -66,7 +66,8 @@ class TestMetadataRepository extends MetadataRepository<Metadata> {
expect(metadata, equals(mapping[node]));
sink.writeByteList(utf8.encode(metadata.string));
sink.writeStringReference(metadata.string);
sink.writeNullAllowedCanonicalNameReference(metadata.member?.canonicalName);
sink.writeNullAllowedCanonicalNameReference(
metadata.member?.reference?.canonicalName);
sink.writeDartType(metadata.type);
}

View file

@ -48,7 +48,7 @@ class DirectCallMetadataRepository
@override
DirectCallMetadata readFromBinary(Node node, BinarySource source) {
final targetReference =
source.readNullableCanonicalNameReference()?.getReference();
source.readNullableCanonicalNameReference()?.reference;
if (targetReference == null) {
throw 'DirectCallMetadata should have a non-null target';
}

View file

@ -128,7 +128,7 @@ class InferredTypeMetadataRepository extends MetadataRepository<InferredType> {
// TODO(sjindel/tfa): Implement serialization of type arguments when can use
// them for optimizations.
final concreteClassReference =
source.readNullableCanonicalNameReference()?.getReference();
source.readNullableCanonicalNameReference()?.reference;
final flags = source.readByte();
final constantValue = (flags & InferredType.flagConstant) != 0
? source.readConstantReference()