Files
sdk/pkg/kernel/lib/reference_from_index.dart
T
Jens Johansen 5fac8d3d71 [CFE] Reproduction and fix of duplicate string-named 'abstract member-signature'
Before this CL, the map we use to "reuse" references when doing
experimental invalidation mapped from String to Reference.
In bug #44523 two abstract member-signatures have the same textual
(String) name meaning that via the lookup one would get the correct
one, one would get the wrong one, they would get the same one
which eventually causes a crash when trying to serialize.

This CL fixes the issue by mapping via the Name instead, which
basically - for private names - wraps the name and the library
which disambiguates it.

This CL also includes the reproduction of #44523.

Fixes #44523.

TEST=Mostly relying on existing test coverage.

Change-Id: Ib62ebca0b7f5092f0b8410d3c458663c3032eca1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177704
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-01-07 13:11:18 +00:00

119 lines
4.0 KiB
Dart

// Copyright (c) 2019, 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"
show
Class,
Constructor,
Extension,
Field,
Library,
Name,
Reference,
Procedure,
Typedef;
class ReferenceFromIndex {
Map<Library, IndexedLibrary> _indexedLibraries =
new Map<Library, IndexedLibrary>.identity();
/// Add an entry mapping from *new* [library] to an index of the old library.
void addIndexedLibrary(Library library, IndexedLibrary indexedLibrary) {
assert(!_indexedLibraries.containsKey(library));
_indexedLibraries[library] = indexedLibrary;
}
/// Lookup the new library and get an index of the old library.
IndexedLibrary lookupLibrary(Library library) => _indexedLibraries[library];
}
abstract class IndexedContainer {
final Map<Name, Reference> _getterReferences = new Map<Name, Reference>();
final Map<Name, Reference> _setterReferences = new Map<Name, Reference>();
Reference lookupGetterReference(Name name) => _getterReferences[name];
Reference lookupSetterReference(Name name) => _setterReferences[name];
Library get library;
void _addProcedures(List<Procedure> procedures) {
for (int i = 0; i < procedures.length; i++) {
Procedure procedure = procedures[i];
Name name = procedure.name;
if (procedure.isSetter) {
assert(_setterReferences[name] == null);
_setterReferences[name] = procedure.reference;
} else {
assert(_getterReferences[name] == null);
_getterReferences[name] = procedure.reference;
}
}
}
void _addFields(List<Field> fields) {
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Name name = field.name;
assert(_getterReferences[name] == null);
_getterReferences[name] = field.getterReference;
if (field.hasSetter) {
assert(_setterReferences[name] == null);
_setterReferences[name] = field.setterReference;
}
}
}
}
class IndexedLibrary extends IndexedContainer {
final Map<String, Typedef> _typedefs = new Map<String, Typedef>();
final Map<String, Class> _classes = new Map<String, Class>();
final Map<String, IndexedClass> _indexedClasses =
new Map<String, IndexedClass>();
final Map<String, Extension> _extensions = new Map<String, Extension>();
final Library library;
IndexedLibrary(this.library) {
for (int i = 0; i < library.typedefs.length; i++) {
Typedef typedef = library.typedefs[i];
assert(_typedefs[typedef.name] == null);
_typedefs[typedef.name] = typedef;
}
for (int i = 0; i < library.classes.length; i++) {
Class c = library.classes[i];
assert(_classes[c.name] == null);
_classes[c.name] = c;
assert(_indexedClasses[c.name] == null);
_indexedClasses[c.name] = new IndexedClass._(c, library);
}
for (int i = 0; i < library.extensions.length; i++) {
Extension extension = library.extensions[i];
assert(_extensions[extension.name] == null);
_extensions[extension.name] = extension;
}
_addProcedures(library.procedures);
_addFields(library.fields);
}
Typedef lookupTypedef(String name) => _typedefs[name];
Class lookupClass(String name) => _classes[name];
IndexedClass lookupIndexedClass(String name) => _indexedClasses[name];
Extension lookupExtension(String name) => _extensions[name];
}
class IndexedClass extends IndexedContainer {
final Map<Name, Constructor> _constructors = new Map<Name, Constructor>();
final Library library;
IndexedClass._(Class c, this.library) {
for (int i = 0; i < c.constructors.length; i++) {
Constructor constructor = c.constructors[i];
_constructors[constructor.name] = constructor;
}
_addProcedures(c.procedures);
_addFields(c.fields);
}
Constructor lookupConstructor(Name name) => _constructors[name];
}