Skip to content

Commit 2765c75

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Improvements for ManifestFunctionType and formal parameters.
Capture more of a function type’s surface by recording formal-parameter metadata and the `covariant` flag in manifests, and by matching them during reuse checks. Encoding now uses each parameter’s `InternalFormalParameterElement`, so we can serialize metadata, covariance, and requiredness directly. Normalize named-parameter handling to reduce churn: - Named parameters are compared in a stable, sorted order; reordering them no longer changes the manifest. - Positional parameters remain order-sensitive. - Type-parameter reordering is invariant when unbounded; when bounds differ, order remains significant. Fix a parameter-iteration bug in `ManifestFunctionType.match` by advancing a single index across positional and named parameters, avoiding off-by-one mismatches when both kinds are present. Remove `operator ==` overrides from manifest types and rely solely on `match()` for structural comparison. This prevents accidental equality misuse and clarifies the intended comparison semantics. Plumb and serialize metadata consistently: - Write/read parameter metadata and covariance in manifests. - Expose `metadata` on `InternalVariableElement`. - Simplify bundle writing by removing an unnecessary cast when writing parameter metadata. Bump the on-disk data version to 528 due to the serialization changes. Overall, this makes manifest matching more precise (catching changes like `@deprecated` or `covariant`) and more stable (ignoring harmless named parameter reorders), improving reuse correctness and reducing manifest churn. Change-Id: Iea2a04339eaa96f63f10ac9852833dd34028845b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447860 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 0c5d46b commit 2765c75

File tree

5 files changed

+751
-184
lines changed

5 files changed

+751
-184
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 = 527;
109+
static const int DATA_VERSION = 528;
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5283,6 +5283,9 @@ mixin InternalSetterElement on InternalPropertyAccessorElement
52835283
}
52845284

52855285
mixin InternalVariableElement implements VariableElement {
5286+
@override
5287+
MetadataImpl get metadata;
5288+
52865289
@override
52875290
TypeImpl get type;
52885291
}

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

Lines changed: 48 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import 'package:analyzer/dart/element/type.dart';
88
import 'package:analyzer/src/dart/element/element.dart';
99
import 'package:analyzer/src/dart/element/type.dart';
1010
import 'package:analyzer/src/fine/manifest_context.dart';
11+
import 'package:analyzer/src/fine/manifest_item.dart';
1112
import 'package:analyzer/src/summary2/data_reader.dart';
1213
import 'package:analyzer/src/summary2/data_writer.dart';
1314
import 'package:analyzer/src/utilities/extensions/collection.dart';
14-
import 'package:collection/collection.dart';
1515

1616
final class ManifestDynamicType extends ManifestType {
1717
static final instance = ManifestDynamicType._();
@@ -30,11 +30,15 @@ final class ManifestDynamicType extends ManifestType {
3030
}
3131

3232
sealed class ManifestFunctionFormalParameter {
33+
final ManifestMetadata metadata;
3334
final bool isRequired;
35+
final bool isCovariant;
3436
final ManifestType type;
3537

3638
ManifestFunctionFormalParameter({
39+
required this.metadata,
3740
required this.isRequired,
41+
required this.isCovariant,
3842
required this.type,
3943
});
4044
}
@@ -44,49 +48,49 @@ class ManifestFunctionNamedFormalParameter
4448
final String name;
4549

4650
factory ManifestFunctionNamedFormalParameter.encode(
47-
EncodeContext context, {
48-
required bool isRequired,
49-
required DartType type,
50-
required String name,
51-
}) {
51+
EncodeContext context,
52+
InternalFormalParameterElement element,
53+
) {
5254
return ManifestFunctionNamedFormalParameter._(
53-
isRequired: isRequired,
54-
type: type.encode(context),
55-
name: name,
55+
metadata: ManifestMetadata.encode(context, element.metadata),
56+
isRequired: element.isRequired,
57+
isCovariant: element.isCovariant,
58+
type: element.type.encode(context),
59+
name: element.name ?? '',
5660
);
5761
}
5862

5963
factory ManifestFunctionNamedFormalParameter.read(SummaryDataReader reader) {
6064
return ManifestFunctionNamedFormalParameter._(
65+
metadata: ManifestMetadata.read(reader),
6166
isRequired: reader.readBool(),
67+
isCovariant: reader.readBool(),
6268
type: ManifestType.read(reader),
6369
name: reader.readStringUtf8(),
6470
);
6571
}
6672

6773
ManifestFunctionNamedFormalParameter._({
74+
required super.metadata,
6875
required super.isRequired,
76+
required super.isCovariant,
6977
required super.type,
7078
required this.name,
7179
});
7280

73-
@override
74-
bool operator ==(Object other) {
75-
if (identical(this, other)) return true;
76-
return other is ManifestFunctionNamedFormalParameter &&
77-
other.name == name &&
78-
other.type == type;
79-
}
80-
8181
bool match(MatchContext context, InternalFormalParameterElement element) {
8282
return element.isNamed &&
83+
metadata.match(context, element.metadata) &&
8384
element.isRequired == isRequired &&
85+
element.isCovariant == isCovariant &&
8486
type.match(context, element.type) &&
8587
element.name == name;
8688
}
8789

8890
void write(BufferedSink sink) {
91+
metadata.write(sink);
8992
sink.writeBool(isRequired);
93+
sink.writeBool(isCovariant);
9094
type.write(sink);
9195
sink.writeStringUtf8(name);
9296
}
@@ -95,46 +99,47 @@ class ManifestFunctionNamedFormalParameter
9599
class ManifestFunctionPositionalFormalParameter
96100
extends ManifestFunctionFormalParameter {
97101
factory ManifestFunctionPositionalFormalParameter.encode(
98-
EncodeContext context, {
99-
required bool isRequired,
100-
required DartType type,
101-
}) {
102+
EncodeContext context,
103+
InternalFormalParameterElement element,
104+
) {
102105
return ManifestFunctionPositionalFormalParameter._(
103-
isRequired: isRequired,
104-
type: type.encode(context),
106+
metadata: ManifestMetadata.encode(context, element.metadata),
107+
isRequired: element.isRequiredPositional,
108+
isCovariant: element.isCovariant,
109+
type: element.type.encode(context),
105110
);
106111
}
107112

108113
factory ManifestFunctionPositionalFormalParameter.read(
109114
SummaryDataReader reader,
110115
) {
111116
return ManifestFunctionPositionalFormalParameter._(
117+
metadata: ManifestMetadata.read(reader),
112118
isRequired: reader.readBool(),
119+
isCovariant: reader.readBool(),
113120
type: ManifestType.read(reader),
114121
);
115122
}
116123

117124
ManifestFunctionPositionalFormalParameter._({
125+
required super.metadata,
118126
required super.isRequired,
127+
required super.isCovariant,
119128
required super.type,
120129
});
121130

122-
@override
123-
bool operator ==(Object other) {
124-
if (identical(this, other)) return true;
125-
return other is ManifestFunctionPositionalFormalParameter &&
126-
other.isRequired == isRequired &&
127-
other.type == type;
128-
}
129-
130131
bool match(MatchContext context, InternalFormalParameterElement element) {
131132
return element.isPositional &&
133+
metadata.match(context, element.metadata) &&
132134
element.isRequired == isRequired &&
135+
element.isCovariant == isCovariant &&
133136
type.match(context, element.type);
134137
}
135138

136139
void write(BufferedSink sink) {
140+
metadata.write(sink);
137141
sink.writeBool(isRequired);
142+
sink.writeBool(isCovariant);
138143
type.write(sink);
139144
}
140145
}
@@ -153,18 +158,17 @@ final class ManifestFunctionType extends ManifestType {
153158
return ManifestFunctionType._(
154159
typeParameters: typeParameters,
155160
returnType: type.returnType.encode(context),
156-
positional: type.positionalParameterTypes.indexed.map((pair) {
157-
return ManifestFunctionPositionalFormalParameter._(
158-
isRequired: pair.$1 < type.requiredPositionalParameterCount,
159-
type: pair.$2.encode(context),
160-
);
161-
}).toFixedList(),
161+
positional: type.formalParameters
162+
.where((element) => element.isPositional)
163+
.map((element) {
164+
return ManifestFunctionPositionalFormalParameter.encode(
165+
context,
166+
element,
167+
);
168+
})
169+
.toFixedList(),
162170
named: type.sortedNamedParametersShared.map((element) {
163-
return ManifestFunctionNamedFormalParameter._(
164-
isRequired: element.isRequired,
165-
type: element.type.encode(context),
166-
name: element.name!,
167-
);
171+
return ManifestFunctionNamedFormalParameter.encode(context, element);
168172
}).toFixedList(),
169173
nullabilitySuffix: type.nullabilitySuffix,
170174
);
@@ -195,21 +199,6 @@ final class ManifestFunctionType extends ManifestType {
195199
required super.nullabilitySuffix,
196200
});
197201

198-
@override
199-
bool operator ==(Object other) {
200-
if (identical(this, other)) return true;
201-
return other is ManifestFunctionType &&
202-
const ListEquality<ManifestFunctionPositionalFormalParameter>().equals(
203-
other.positional,
204-
positional,
205-
) &&
206-
const ListEquality<ManifestFunctionNamedFormalParameter>().equals(
207-
other.named,
208-
named,
209-
) &&
210-
other.nullabilitySuffix == nullabilitySuffix;
211-
}
212-
213202
@override
214203
bool match(MatchContext context, DartType type) {
215204
if (type is! FunctionTypeImpl) {
@@ -229,7 +218,7 @@ final class ManifestFunctionType extends ManifestType {
229218
var index = 0;
230219

231220
for (var i = 0; i < positional.length; i++) {
232-
if (i >= formalParameters.length) {
221+
if (index >= formalParameters.length) {
233222
return false;
234223
}
235224
var manifest = positional[i];
@@ -240,7 +229,7 @@ final class ManifestFunctionType extends ManifestType {
240229
}
241230

242231
for (var i = 0; i < named.length; i++) {
243-
if (i >= formalParameters.length) {
232+
if (index >= formalParameters.length) {
244233
return false;
245234
}
246235
var manifest = named[i];
@@ -309,15 +298,6 @@ final class ManifestInterfaceType extends ManifestType {
309298
required super.nullabilitySuffix,
310299
});
311300

312-
@override
313-
bool operator ==(Object other) {
314-
if (identical(this, other)) return true;
315-
return other is ManifestInterfaceType &&
316-
other.element == element &&
317-
const ListEquality<ManifestType>().equals(other.arguments, arguments) &&
318-
other.nullabilitySuffix == nullabilitySuffix;
319-
}
320-
321301
@override
322302
bool match(MatchContext context, DartType type) {
323303
if (type is! InterfaceType) {
@@ -384,13 +364,6 @@ final class ManifestNeverType extends ManifestType {
384364

385365
ManifestNeverType._({required super.nullabilitySuffix});
386366

387-
@override
388-
bool operator ==(Object other) {
389-
if (identical(this, other)) return true;
390-
return other is ManifestNeverType &&
391-
other.nullabilitySuffix == nullabilitySuffix;
392-
}
393-
394367
@override
395368
bool match(MatchContext context, DartType type) {
396369
if (type is! NeverTypeImpl) {
@@ -448,21 +421,6 @@ final class ManifestRecordType extends ManifestType {
448421
required super.nullabilitySuffix,
449422
});
450423

451-
@override
452-
bool operator ==(Object other) {
453-
if (identical(this, other)) return true;
454-
return other is ManifestRecordType &&
455-
const ListEquality<ManifestType>().equals(
456-
other.positionalFields,
457-
positionalFields,
458-
) &&
459-
const ListEquality<ManifestRecordTypeNamedField>().equals(
460-
other.namedFields,
461-
namedFields,
462-
) &&
463-
other.nullabilitySuffix == nullabilitySuffix;
464-
}
465-
466424
@override
467425
bool match(MatchContext context, DartType type) {
468426
if (type is! RecordType) {
@@ -530,14 +488,6 @@ class ManifestRecordTypeNamedField {
530488

531489
ManifestRecordTypeNamedField._({required this.name, required this.type});
532490

533-
@override
534-
bool operator ==(Object other) {
535-
if (identical(this, other)) return true;
536-
return other is ManifestRecordTypeNamedField &&
537-
other.name == name &&
538-
other.type == type;
539-
}
540-
541491
bool match(MatchContext context, RecordTypeNamedField field) {
542492
return field.name == name && type.match(context, field.type);
543493
}
@@ -604,12 +554,6 @@ class ManifestTypeParameter {
604554

605555
ManifestTypeParameter._({required this.bound});
606556

607-
@override
608-
bool operator ==(Object other) {
609-
if (identical(this, other)) return true;
610-
return other is ManifestTypeParameter && other.bound == bound;
611-
}
612-
613557
bool match(MatchContext context, TypeParameterElement element) {
614558
return bound.match(context, element.bound);
615559
}
@@ -648,14 +592,6 @@ final class ManifestTypeParameterType extends ManifestType {
648592
required super.nullabilitySuffix,
649593
});
650594

651-
@override
652-
bool operator ==(Object other) {
653-
if (identical(this, other)) return true;
654-
return other is ManifestTypeParameterType &&
655-
other.index == index &&
656-
other.nullabilitySuffix == nullabilitySuffix;
657-
}
658-
659595
@override
660596
bool match(MatchContext context, DartType type) {
661597
if (type is! TypeParameterTypeImpl) {

pkg/analyzer/lib/src/summary2/bundle_writer.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ class ResolutionSink extends _SummaryDataWriter {
10451045
);
10461046
}, withAnnotations: withAnnotations);
10471047
if (withAnnotations) {
1048-
_writeMetadata(parameter.metadata as MetadataImpl);
1048+
_writeMetadata(parameter.metadata);
10491049
}
10501050
});
10511051
}

0 commit comments

Comments
 (0)