Skip to content

Commit 3117e40

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Record requested fields.
Directly with `getField`, or indirectly via getter/setter. Many `test_dependency_` switched to `instanceFieldIdMismatch` because almost any use of a getter / setter in code like `x.foo` end up requesting the field while resolving. Change-Id: I5e7d68c6e8a055e60e8d5feeee838df3f6c5b1d7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/428301 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 3e13465 commit 3117e40

File tree

6 files changed

+1543
-185
lines changed

6 files changed

+1543
-185
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4436,6 +4436,7 @@ class HideElementCombinatorImpl implements HideElementCombinator {
44364436
}
44374437
}
44384438

4439+
@elementClass
44394440
abstract class InstanceElementImpl2 extends ElementImpl2
44404441
implements
44414442
InstanceElement,
@@ -4540,11 +4541,18 @@ abstract class InstanceElementImpl2 extends ElementImpl2
45404541
);
45414542

45424543
@override
4544+
@trackedDirectly
45434545
FieldElementImpl2? getField2(String name) {
4546+
globalResultRequirements?.record_instanceElement_getField(
4547+
element: this,
4548+
name: name,
4549+
);
4550+
45444551
return fields2.firstWhereOrNull((e) => e.name3 == name);
45454552
}
45464553

45474554
@override
4555+
@trackedDirectly
45484556
GetterElementImpl? getGetter2(String name) {
45494557
globalResultRequirements?.record_instanceElement_getGetter(
45504558
element: this,
@@ -4555,6 +4563,7 @@ abstract class InstanceElementImpl2 extends ElementImpl2
45554563
}
45564564

45574565
@override
4566+
@trackedDirectly
45584567
MethodElementImpl2? getMethod2(String name) {
45594568
globalResultRequirements?.record_instanceElement_getMethod(
45604569
element: this,
@@ -4565,6 +4574,7 @@ abstract class InstanceElementImpl2 extends ElementImpl2
45654574
}
45664575

45674576
@override
4577+
@trackedDirectly
45684578
SetterElementImpl? getSetter2(String name) {
45694579
globalResultRequirements?.record_instanceElement_getSetter(
45704580
element: this,
@@ -8469,7 +8479,13 @@ abstract class PropertyAccessorElementImpl2 extends ExecutableElementImpl2
84698479
String? get name3 => firstFragment.name2;
84708480

84718481
@override
8482+
@trackedDirectly
84728483
PropertyInducingElementImpl2? get variable3 {
8484+
globalResultRequirements?.record_propertyAccessorElement_variable(
8485+
element: this,
8486+
name: name3,
8487+
);
8488+
84738489
return firstFragment.variable2?.element;
84748490
}
84758491
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ sealed class InstanceItem<E extends InstanceElementImpl2>
104104
return baseNameMembers.constructorId;
105105
}
106106

107+
ManifestItemId? getDeclaredFieldId(LookupName name) {
108+
return declaredFields[name]?.id;
109+
}
110+
107111
ManifestItemId? getDeclaredMemberId(LookupName name) {
108112
var baseNameMembers = declaredMembers[name.asBaseName];
109113
if (baseNameMembers == null) {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,22 @@ final class ExportLibraryMissing extends ExportFailure {
4444
ExportLibraryMissing({required this.uri});
4545
}
4646

47+
class InstanceFieldIdMismatch extends RequirementFailure {
48+
final Uri libraryUri;
49+
final LookupName interfaceName;
50+
final LookupName fieldName;
51+
final ManifestItemId? expectedId;
52+
final ManifestItemId? actualId;
53+
54+
InstanceFieldIdMismatch({
55+
required this.libraryUri,
56+
required this.interfaceName,
57+
required this.fieldName,
58+
required this.expectedId,
59+
required this.actualId,
60+
});
61+
}
62+
4763
class InstanceMethodIdMismatch extends RequirementFailure {
4864
final Uri libraryUri;
4965
final LookupName interfaceName;

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

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -190,20 +190,29 @@ final class ExportRequirementShowCombinator
190190
/// If [InterfaceElementImpl2], there are additional requirements in form
191191
/// of [InterfaceItemRequirements].
192192
class InstanceItemRequirements {
193+
final Map<LookupName, ManifestItemId?> requestedFields;
194+
193195
/// These are "methods" in wide meaning: methods, getters, setters.
194196
final Map<LookupName, ManifestItemId?> requestedMethods;
195197

196-
InstanceItemRequirements({required this.requestedMethods});
198+
InstanceItemRequirements({
199+
required this.requestedFields,
200+
required this.requestedMethods,
201+
});
197202

198203
factory InstanceItemRequirements.empty() {
199-
return InstanceItemRequirements(requestedMethods: {});
204+
return InstanceItemRequirements(requestedFields: {}, requestedMethods: {});
200205
}
201206

202207
factory InstanceItemRequirements.read(SummaryDataReader reader) {
203-
return InstanceItemRequirements(requestedMethods: reader.readNameToIdMap());
208+
return InstanceItemRequirements(
209+
requestedFields: reader.readNameToIdMap(),
210+
requestedMethods: reader.readNameToIdMap(),
211+
);
204212
}
205213

206214
void write(BufferedSink sink) {
215+
sink.writeNameToIdMap(requestedFields);
207216
sink.writeNameToIdMap(requestedMethods);
208217
}
209218
}
@@ -349,6 +358,8 @@ class RequirementsManifest {
349358

350359
for (var instanceEntry in libraryEntry.value.entries) {
351360
var instanceName = instanceEntry.key;
361+
var requirements = instanceEntry.value;
362+
352363
var instanceItem = libraryManifest.items[instanceName];
353364
if (instanceItem is! InstanceItem) {
354365
return TopLevelNotInterface(
@@ -357,18 +368,32 @@ class RequirementsManifest {
357368
);
358369
}
359370

360-
var methods = instanceEntry.value.requestedMethods;
361-
for (var methodEntry in methods.entries) {
362-
var methodName = methodEntry.key;
363-
var methodId = instanceItem.getDeclaredMemberId(methodName);
371+
for (var fieldEntry in requirements.requestedFields.entries) {
372+
var name = fieldEntry.key;
373+
var expectedId = fieldEntry.value;
374+
var currentId = instanceItem.getDeclaredFieldId(name);
375+
if (expectedId != currentId) {
376+
return InstanceFieldIdMismatch(
377+
libraryUri: libraryUri,
378+
interfaceName: instanceName,
379+
fieldName: name,
380+
expectedId: expectedId,
381+
actualId: currentId,
382+
);
383+
}
384+
}
385+
386+
for (var methodEntry in requirements.requestedMethods.entries) {
387+
var name = methodEntry.key;
364388
var expectedId = methodEntry.value;
365-
if (expectedId != methodId) {
389+
var currentId = instanceItem.getDeclaredMemberId(name);
390+
if (expectedId != currentId) {
366391
return InstanceMethodIdMismatch(
367392
libraryUri: libraryUri,
368393
interfaceName: instanceName,
369-
methodName: methodName,
394+
methodName: name,
370395
expectedId: expectedId,
371-
actualId: methodId,
396+
actualId: currentId,
372397
);
373398
}
374399
}
@@ -529,6 +554,23 @@ class RequirementsManifest {
529554
// TODO(scheglov): implement.
530555
}
531556

557+
void record_instanceElement_getField({
558+
required InstanceElementImpl2 element,
559+
required String name,
560+
}) {
561+
var itemRequirements = _getInstanceItem(element);
562+
if (itemRequirements == null) {
563+
return;
564+
}
565+
566+
var item = itemRequirements.item;
567+
var requirements = itemRequirements.requirements;
568+
569+
var fieldName = name.asLookupName;
570+
var fieldId = item.getDeclaredFieldId(fieldName);
571+
requirements.requestedFields[fieldName] = fieldId;
572+
}
573+
532574
void record_instanceElement_getGetter({
533575
required InstanceElementImpl2 element,
534576
required String name,
@@ -560,6 +602,22 @@ class RequirementsManifest {
560602
record_instanceElement_getMethod(element: element, name: '$name=');
561603
}
562604

605+
void record_propertyAccessorElement_variable({
606+
required PropertyAccessorElementImpl2 element,
607+
required String? name,
608+
}) {
609+
if (name == null) {
610+
return;
611+
}
612+
613+
switch (element.enclosingElement2) {
614+
case InstanceElementImpl2 instanceElement:
615+
record_instanceElement_getField(element: instanceElement, name: name);
616+
default:
617+
// TODO(scheglov): support for top-level variables
618+
}
619+
}
620+
563621
/// This method is invoked after linking of a library cycle, to exclude
564622
/// requirements to the libraries of this same library cycle. We already
565623
/// link these libraries together, so only requirements to the previous

0 commit comments

Comments
 (0)