Skip to content

Commit 3cc5f56

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Persist isSimplyBounded; track isValidMixin indirectly.
Capture the simply-boundedness of instance elements in the fine-grained manifest and stop baking `isValidMixin` into item IDs. What: - Add `isSimplyBounded` to `InstanceItem` and all subclasses (`ClassItem`, `EnumItem`, `ExtensionItem`, `ExtensionTypeItem`, `MixinItem`). Persist it in summaries and compare it in `match`. - Update the summary schema to write/read `isSimplyBounded` immediately after `typeParameters` for all instance items. - Reclassify `ClassElementImpl.isValidMixin` from `@trackedIncludedInId` to `@trackedIndirectly`. - Bump `AnalysisDriver.DATA_VERSION` from 533 to 536. Why: - `isSimplyBounded` is an observable property of generic declarations. Not recording it could allow identity reuse when simply-boundedness changes without other shape differences. Persisting it yields more precise matching and invalidation. - `isValidMixin` is derived from other fields (e.g., `supertype`, constructors). Tracking it indirectly avoids unnecessary ID churn and reduces over-invalidation while remaining responsive to the inputs it depends on. Impact: - More accurate fine-grained dependency tracking for generics. - Fewer spurious item-ID changes from mixin validity checks. - Existing caches are invalidated due to the data format bump; no public API changes. Change-Id: I2700b16add664a4fd127f492fb186c8e1f3635e9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448100 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Paul Berry <[email protected]>
1 parent 579ad24 commit 3cc5f56

File tree

4 files changed

+154
-3
lines changed

4 files changed

+154
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ testFineAfterLibraryAnalyzerHook;
106106
// TODO(scheglov): Clean up the list of implicitly analyzed files.
107107
class AnalysisDriver {
108108
/// The version of data format, should be incremented on every format change.
109-
static const int DATA_VERSION = 534;
109+
static const int DATA_VERSION = 536;
110110

111111
/// The number of exception contexts allowed to write. Once this field is
112112
/// zero, we stop writing any new exception contexts in this process.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ class ClassElementImpl extends InterfaceElementImpl implements ClassElement {
338338
}
339339

340340
@override
341-
@trackedIncludedInId
341+
@trackedIndirectly
342342
bool get isValidMixin {
343343
var supertype = this.supertype;
344344
if (supertype != null && !supertype.isDartCoreObject) {

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ClassItem extends InterfaceItem<ClassElementImpl> {
2828
required super.id,
2929
required super.metadata,
3030
required super.typeParameters,
31+
required super.isSimplyBounded,
3132
required super.declaredConflicts,
3233
required super.declaredFields,
3334
required super.declaredGetters,
@@ -58,6 +59,7 @@ class ClassItem extends InterfaceItem<ClassElementImpl> {
5859
id: id,
5960
metadata: ManifestMetadata.encode(context, element.metadata),
6061
typeParameters: typeParameters,
62+
isSimplyBounded: element.isSimplyBounded,
6163
declaredConflicts: {},
6264
declaredFields: {},
6365
declaredGetters: {},
@@ -85,6 +87,7 @@ class ClassItem extends InterfaceItem<ClassElementImpl> {
8587
id: ManifestItemId.read(reader),
8688
metadata: ManifestMetadata.read(reader),
8789
typeParameters: ManifestTypeParameter.readList(reader),
90+
isSimplyBounded: reader.readBool(),
8891
declaredConflicts: reader.readLookupNameToIdMap(),
8992
declaredFields: InstanceItemFieldItem.readMap(reader),
9093
declaredGetters: InstanceItemGetterItem.readMap(reader),
@@ -136,6 +139,7 @@ class EnumItem extends InterfaceItem<EnumElementImpl> {
136139
required super.id,
137140
required super.metadata,
138141
required super.typeParameters,
142+
required super.isSimplyBounded,
139143
required super.declaredConflicts,
140144
required super.declaredFields,
141145
required super.declaredGetters,
@@ -159,6 +163,7 @@ class EnumItem extends InterfaceItem<EnumElementImpl> {
159163
id: id,
160164
metadata: ManifestMetadata.encode(context, element.metadata),
161165
typeParameters: typeParameters,
166+
isSimplyBounded: element.isSimplyBounded,
162167
declaredConflicts: {},
163168
declaredFields: {},
164169
declaredGetters: {},
@@ -179,6 +184,7 @@ class EnumItem extends InterfaceItem<EnumElementImpl> {
179184
id: ManifestItemId.read(reader),
180185
metadata: ManifestMetadata.read(reader),
181186
typeParameters: ManifestTypeParameter.readList(reader),
187+
isSimplyBounded: reader.readBool(),
182188
declaredConflicts: reader.readLookupNameToIdMap(),
183189
declaredFields: InstanceItemFieldItem.readMap(reader),
184190
declaredGetters: InstanceItemGetterItem.readMap(reader),
@@ -202,6 +208,7 @@ class ExtensionItem<E extends ExtensionElementImpl> extends InstanceItem<E> {
202208
required super.id,
203209
required super.metadata,
204210
required super.typeParameters,
211+
required super.isSimplyBounded,
205212
required super.declaredConflicts,
206213
required super.declaredFields,
207214
required super.declaredGetters,
@@ -222,6 +229,7 @@ class ExtensionItem<E extends ExtensionElementImpl> extends InstanceItem<E> {
222229
id: id,
223230
metadata: ManifestMetadata.encode(context, element.metadata),
224231
typeParameters: typeParameters,
232+
isSimplyBounded: element.isSimplyBounded,
225233
declaredConflicts: {},
226234
declaredFields: {},
227235
declaredGetters: {},
@@ -239,6 +247,7 @@ class ExtensionItem<E extends ExtensionElementImpl> extends InstanceItem<E> {
239247
id: ManifestItemId.read(reader),
240248
metadata: ManifestMetadata.read(reader),
241249
typeParameters: ManifestTypeParameter.readList(reader),
250+
isSimplyBounded: reader.readBool(),
242251
declaredConflicts: reader.readLookupNameToIdMap(),
243252
declaredFields: InstanceItemFieldItem.readMap(reader),
244253
declaredGetters: InstanceItemGetterItem.readMap(reader),
@@ -273,6 +282,7 @@ class ExtensionTypeItem extends InterfaceItem<ExtensionTypeElementImpl> {
273282
required super.id,
274283
required super.metadata,
275284
required super.typeParameters,
285+
required super.isSimplyBounded,
276286
required super.declaredConflicts,
277287
required super.declaredFields,
278288
required super.declaredGetters,
@@ -300,6 +310,7 @@ class ExtensionTypeItem extends InterfaceItem<ExtensionTypeElementImpl> {
300310
id: id,
301311
metadata: ManifestMetadata.encode(context, element.metadata),
302312
typeParameters: typeParameters,
313+
isSimplyBounded: element.isSimplyBounded,
303314
declaredConflicts: {},
304315
declaredFields: {},
305316
declaredGetters: {},
@@ -324,6 +335,7 @@ class ExtensionTypeItem extends InterfaceItem<ExtensionTypeElementImpl> {
324335
id: ManifestItemId.read(reader),
325336
metadata: ManifestMetadata.read(reader),
326337
typeParameters: ManifestTypeParameter.readList(reader),
338+
isSimplyBounded: reader.readBool(),
327339
declaredConflicts: reader.readLookupNameToIdMap(),
328340
declaredFields: InstanceItemFieldItem.readMap(reader),
329341
declaredGetters: InstanceItemGetterItem.readMap(reader),
@@ -366,6 +378,7 @@ class ExtensionTypeItem extends InterfaceItem<ExtensionTypeElementImpl> {
366378
sealed class InstanceItem<E extends InstanceElementImpl>
367379
extends TopLevelItem<E> {
368380
final List<ManifestTypeParameter> typeParameters;
381+
final bool isSimplyBounded;
369382

370383
/// The names of duplicate or otherwise conflicting members.
371384
/// Such names will not be added to `declaredXyz` maps.
@@ -382,6 +395,7 @@ sealed class InstanceItem<E extends InstanceElementImpl>
382395
required super.id,
383396
required super.metadata,
384397
required this.typeParameters,
398+
required this.isSimplyBounded,
385399
required this.declaredConflicts,
386400
required this.declaredFields,
387401
required this.declaredGetters,
@@ -550,13 +564,15 @@ sealed class InstanceItem<E extends InstanceElementImpl>
550564
bool match(MatchContext context, E element) {
551565
context.addTypeParameters(element.typeParameters);
552566
return super.match(context, element) &&
553-
typeParameters.match(context, element.typeParameters);
567+
typeParameters.match(context, element.typeParameters) &&
568+
isSimplyBounded == element.isSimplyBounded;
554569
}
555570

556571
@override
557572
void write(BufferedSink sink) {
558573
super.write(sink);
559574
typeParameters.write(sink);
575+
sink.writeBool(isSimplyBounded);
560576
declaredConflicts.write(sink);
561577
declaredFields.write(sink);
562578
declaredGetters.write(sink);
@@ -918,6 +934,7 @@ sealed class InterfaceItem<E extends InterfaceElementImpl>
918934
required super.id,
919935
required super.metadata,
920936
required super.typeParameters,
937+
required super.isSimplyBounded,
921938
required super.declaredConflicts,
922939
required super.declaredFields,
923940
required super.declaredGetters,
@@ -1220,6 +1237,7 @@ class MixinItem extends InterfaceItem<MixinElementImpl> {
12201237
required super.id,
12211238
required super.metadata,
12221239
required super.typeParameters,
1240+
required super.isSimplyBounded,
12231241
required super.supertype,
12241242
required super.interfaces,
12251243
required super.mixins,
@@ -1248,6 +1266,7 @@ class MixinItem extends InterfaceItem<MixinElementImpl> {
12481266
id: id,
12491267
metadata: ManifestMetadata.encode(context, element.metadata),
12501268
typeParameters: typeParameters,
1269+
isSimplyBounded: element.isSimplyBounded,
12511270
declaredConflicts: {},
12521271
declaredFields: {},
12531272
declaredGetters: {},
@@ -1273,6 +1292,7 @@ class MixinItem extends InterfaceItem<MixinElementImpl> {
12731292
id: ManifestItemId.read(reader),
12741293
metadata: ManifestMetadata.read(reader),
12751294
typeParameters: ManifestTypeParameter.readList(reader),
1295+
isSimplyBounded: reader.readBool(),
12761296
declaredConflicts: reader.readLookupNameToIdMap(),
12771297
declaredFields: InstanceItemFieldItem.readMap(reader),
12781298
declaredGetters: InstanceItemGetterItem.readMap(reader),

pkg/analyzer/test/src/dart/analysis/driver_test.dart

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12278,6 +12278,105 @@ class A {
1227812278
);
1227912279
}
1228012280

12281+
test_dependency_class_namedConstructor_add_isValidMixin() async {
12282+
configuration.withStreamResolvedUnitResults = false;
12283+
12284+
_ManualRequirements.install((state) {
12285+
state.singleUnit.scopeClassElement('A').isValidMixin;
12286+
});
12287+
12288+
await _runChangeScenarioTA(
12289+
initialA: r'''
12290+
class A {}
12291+
''',
12292+
testCode: r'''
12293+
import 'a.dart';
12294+
''',
12295+
operation: _FineOperationTestFileGetErrors(),
12296+
expectedInitialEvents: r'''
12297+
[status] working
12298+
[operation] linkLibraryCycle SDK
12299+
[operation] linkLibraryCycle
12300+
package:test/a.dart
12301+
declaredClasses
12302+
A: #M0
12303+
interface: #M1
12304+
requirements
12305+
[operation] linkLibraryCycle
12306+
package:test/test.dart
12307+
requirements
12308+
[operation] analyzeFile
12309+
file: /home/test/lib/test.dart
12310+
library: /home/test/lib/test.dart
12311+
[operation] analyzedLibrary
12312+
file: /home/test/lib/test.dart
12313+
requirements
12314+
libraries
12315+
package:test/a.dart
12316+
exportedTopLevels
12317+
A: #M0
12318+
interfaces
12319+
A
12320+
allConstructors: #M2
12321+
[status] idle
12322+
[future] getErrors T1
12323+
ErrorsResult #0
12324+
path: /home/test/lib/test.dart
12325+
uri: package:test/test.dart
12326+
flags: isLibrary
12327+
errors
12328+
7 +8 UNUSED_IMPORT
12329+
''',
12330+
updatedA: r'''
12331+
class A {
12332+
A.named();
12333+
}
12334+
''',
12335+
expectedUpdatedEvents: r'''
12336+
[status] working
12337+
[operation] linkLibraryCycle
12338+
package:test/a.dart
12339+
declaredClasses
12340+
A: #M0
12341+
declaredConstructors
12342+
named: #M3
12343+
interface: #M1
12344+
requirements
12345+
[operation] reuseLinkedBundle
12346+
package:test/test.dart
12347+
[operation] checkLibraryDiagnosticsRequirements
12348+
library: /home/test/lib/test.dart
12349+
interfaceChildrenIdsMismatch
12350+
libraryUri: package:test/a.dart
12351+
interfaceName: A
12352+
childrenPropertyName: constructors
12353+
expectedIds: #M2
12354+
actualIds: #M3
12355+
[operation] analyzeFile
12356+
file: /home/test/lib/test.dart
12357+
library: /home/test/lib/test.dart
12358+
[operation] analyzedLibrary
12359+
file: /home/test/lib/test.dart
12360+
requirements
12361+
libraries
12362+
package:test/a.dart
12363+
exportedTopLevels
12364+
A: #M0
12365+
interfaces
12366+
A
12367+
allConstructors: #M3
12368+
[status] idle
12369+
[future] getErrors T2
12370+
ErrorsResult #1
12371+
path: /home/test/lib/test.dart
12372+
uri: package:test/test.dart
12373+
flags: isLibrary
12374+
errors
12375+
7 +8 UNUSED_IMPORT
12376+
''',
12377+
);
12378+
}
12379+
1228112380
test_dependency_class_namedConstructor_change_getConstructors() async {
1228212381
configuration.includeDefaultConstructors();
1228312382

@@ -44680,6 +44779,38 @@ class D {}
4468044779
);
4468144780
}
4468244781

44782+
test_manifest_class_modifier_isSimplyBounded() async {
44783+
await _runLibraryManifestScenario(
44784+
initialCode: r'''
44785+
class A<T> {}
44786+
class B<T extends List<T>> {}
44787+
''',
44788+
expectedInitialEvents: r'''
44789+
[operation] linkLibraryCycle SDK
44790+
[operation] linkLibraryCycle
44791+
package:test/test.dart
44792+
declaredClasses
44793+
A: #M0
44794+
interface: #M1
44795+
B: #M2
44796+
interface: #M3
44797+
''',
44798+
updatedCode: r'''
44799+
class A<T extends List<T>> {}
44800+
class B<T> {}
44801+
''',
44802+
expectedUpdatedEvents: r'''
44803+
[operation] linkLibraryCycle
44804+
package:test/test.dart
44805+
declaredClasses
44806+
A: #M4
44807+
interface: #M5
44808+
B: #M6
44809+
interface: #M7
44810+
''',
44811+
);
44812+
}
44813+
4468344814
test_manifest_class_private() async {
4468444815
await _runLibraryManifestScenario(
4468544816
initialCode: r'''

0 commit comments

Comments
 (0)