Skip to content

Commit 012d84a

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Record requesting the whole interface.
We give the interface its own ID to track its changes. We also stop collecting requirements of a summary bundle _after_ computing library manifests for it, because any data that we put into library manifests depends on what we requested while computing it, not much different than the summary / elements themselves. Specifically, interfaces for classes have `map` of all class members, and it depends on the interfaces of superclasses. And we ask for interfaces of classes only when computing library manifests, somehow we avoided doing this while linking libraries. test_dependency_class_interface_addMethod would not work without these changes. Change-Id: I14858bab48ff2ada8df32b8440b8f18eb743d061 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431000 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Paul Berry <[email protected]>
1 parent e2fdf18 commit 012d84a

File tree

7 files changed

+4932
-4256
lines changed

7 files changed

+4932
-4256
lines changed

pkg/analyzer/lib/src/dart/analysis/library_context.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ class LibraryContext {
218218
inputLibraryManifests: inputLibraryManifests,
219219
);
220220
});
221-
globalResultRequirements = null;
222221
linkedBytes = linkResult.resolutionBytes;
223222

224223
var newLibraryManifests = <Uri, LibraryManifest>{};
@@ -235,6 +234,7 @@ class LibraryContext {
235234
elementFactory: elementFactory,
236235
libraryUriSet: cycle.libraryUris,
237236
);
237+
globalResultRequirements = null;
238238
requirements.removeReqForLibs(cycle.libraryUris);
239239

240240
bundleEntry = LinkedBundleEntry(

pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ class InheritanceManager3 {
287287
@experimental
288288
Interface getInterface2(InterfaceElement element) {
289289
element as InterfaceElementImpl2; // TODO(scheglov): remove cast
290+
globalResultRequirements?.record_interface_all(element: element);
290291
return getInterface(element.asElement);
291292
}
292293

pkg/analyzer/lib/src/fine/manifest_item.dart

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:analyzer/src/fine/manifest_type.dart';
1212
import 'package:analyzer/src/summary2/data_reader.dart';
1313
import 'package:analyzer/src/summary2/data_writer.dart';
1414
import 'package:analyzer/src/utilities/extensions/collection.dart';
15+
import 'package:collection/collection.dart';
1516
import 'package:meta/meta.dart';
1617

1718
class ClassItem extends InterfaceItem<ClassElementImpl2> {
@@ -987,8 +988,16 @@ class ManifestAnnotation {
987988
/// type. So, any such code depends on the header of the class, so includes
988989
/// the type arguments for the class that declares the inherited member.
989990
class ManifestInterface {
991+
/// The ID of the interface, stays the same if all information in the
992+
/// interface is the same.
993+
ManifestItemId id;
994+
990995
/// The map of names to their IDs in the interface.
991-
final Map<LookupName, ManifestItemId> map;
996+
Map<LookupName, ManifestItemId> map;
997+
998+
/// We move [map] into here during building the manifest, so that we can
999+
/// compare after building, and decide if [id] should be updated.
1000+
Map<LookupName, ManifestItemId> mapPrevious = {};
9921001

9931002
/// Key: IDs of method declarations.
9941003
/// Value: ID assigned last time.
@@ -999,14 +1008,23 @@ class ManifestInterface {
9991008
/// we can fill [combinedIds] with new entries.
10001009
Map<ManifestItemIdList, ManifestItemId> combinedIdsTemp = {};
10011010

1002-
ManifestInterface({required this.map, required this.combinedIds});
1011+
ManifestInterface({
1012+
required this.id,
1013+
required this.map,
1014+
required this.combinedIds,
1015+
});
10031016

10041017
factory ManifestInterface.empty() {
1005-
return ManifestInterface(map: {}, combinedIds: {});
1018+
return ManifestInterface(
1019+
id: ManifestItemId.generate(),
1020+
map: {},
1021+
combinedIds: {},
1022+
);
10061023
}
10071024

10081025
factory ManifestInterface.read(SummaryDataReader reader) {
10091026
return ManifestInterface(
1027+
id: ManifestItemId.read(reader),
10101028
map: reader.readLookupNameToIdMap(),
10111029
combinedIds: reader.readMap(
10121030
readKey: () => ManifestItemIdList.read(reader),
@@ -1016,16 +1034,25 @@ class ManifestInterface {
10161034
}
10171035

10181036
void afterUpdate() {
1037+
const mapEquality = MapEquality<LookupName, ManifestItemId>();
1038+
if (!mapEquality.equals(map, mapPrevious)) {
1039+
id = ManifestItemId.generate();
1040+
}
1041+
mapPrevious = {};
1042+
10191043
combinedIdsTemp = {};
10201044
}
10211045

10221046
void beforeUpdating() {
1023-
map.clear();
1047+
mapPrevious = map;
1048+
map = {};
1049+
10241050
combinedIdsTemp = combinedIds;
10251051
combinedIds = {};
10261052
}
10271053

10281054
void write(BufferedSink sink) {
1055+
id.write(sink);
10291056
map.write(sink);
10301057
sink.writeMap(
10311058
combinedIds,

pkg/analyzer/lib/src/fine/requirement_failure.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,20 @@ class InterfaceConstructorIdMismatch extends RequirementFailure {
106106
});
107107
}
108108

109+
class InterfaceIdMismatch extends RequirementFailure {
110+
final Uri libraryUri;
111+
final LookupName interfaceName;
112+
final ManifestItemId expectedId;
113+
final ManifestItemId actualId;
114+
115+
InterfaceIdMismatch({
116+
required this.libraryUri,
117+
required this.interfaceName,
118+
required this.expectedId,
119+
required this.actualId,
120+
});
121+
}
122+
109123
class LibraryMissing extends RequirementFailure {
110124
final Uri uri;
111125

pkg/analyzer/lib/src/fine/requirements.dart

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,28 +247,38 @@ class InstanceItemRequirements {
247247
/// Includes all requirements from class-like items: classes, enums,
248248
/// extension types, mixins.
249249
class InterfaceItemRequirements {
250+
/// If the element was asked for its full interface.
251+
ManifestItemId? interfaceId;
252+
250253
final Map<LookupName, ManifestItemId?> constructors;
251254

252255
/// These are "methods" in wide meaning: methods, getters, setters.
253256
final Map<LookupName, ManifestItemId?> methods;
254257

255258
InterfaceItemRequirements({
259+
required this.interfaceId,
256260
required this.constructors,
257261
required this.methods,
258262
});
259263

260264
factory InterfaceItemRequirements.empty() {
261-
return InterfaceItemRequirements(constructors: {}, methods: {});
265+
return InterfaceItemRequirements(
266+
interfaceId: null,
267+
constructors: {},
268+
methods: {},
269+
);
262270
}
263271

264272
factory InterfaceItemRequirements.read(SummaryDataReader reader) {
265273
return InterfaceItemRequirements(
274+
interfaceId: ManifestItemId.readOptional(reader),
266275
constructors: reader.readNameToIdMap(),
267276
methods: reader.readNameToIdMap(),
268277
);
269278
}
270279

271280
void write(BufferedSink sink) {
281+
interfaceId.writeOptional(sink);
272282
sink.writeNameToIdMap(constructors);
273283
sink.writeNameToIdMap(methods);
274284
}
@@ -538,7 +548,20 @@ class RequirementsManifest {
538548
);
539549
}
540550

541-
var constructors = interfaceEntry.value.constructors;
551+
var interfaceRequirements = interfaceEntry.value;
552+
if (interfaceRequirements.interfaceId case var expectedId?) {
553+
var actualId = interfaceItem.interface.id;
554+
if (expectedId != actualId) {
555+
return InterfaceIdMismatch(
556+
libraryUri: libraryUri,
557+
interfaceName: interfaceName,
558+
expectedId: expectedId,
559+
actualId: actualId,
560+
);
561+
}
562+
}
563+
564+
var constructors = interfaceRequirements.constructors;
542565
for (var constructorEntry in constructors.entries) {
543566
var constructorName = constructorEntry.key;
544567
var constructorId = interfaceItem.getConstructorId(constructorName);
@@ -554,7 +577,7 @@ class RequirementsManifest {
554577
}
555578
}
556579

557-
var methods = interfaceEntry.value.methods;
580+
var methods = interfaceRequirements.methods;
558581
for (var methodEntry in methods.entries) {
559582
var methodName = methodEntry.key;
560583
var methodId = interfaceItem.getInterfaceMethodId(methodName);
@@ -705,6 +728,16 @@ class RequirementsManifest {
705728
);
706729
}
707730

731+
void record_interface_all({required InterfaceElementImpl2 element}) {
732+
var itemRequirements = _getInterfaceItem(element);
733+
if (itemRequirements == null) {
734+
return;
735+
}
736+
737+
var interface = itemRequirements.item.interface;
738+
itemRequirements.requirements.interfaceId = interface.id;
739+
}
740+
708741
/// Record that a member with [nameObj] was requested from the interface
709742
/// of [element]. The [methodElement] is used for consistency checking.
710743
void record_interface_getMember({

0 commit comments

Comments
 (0)