Skip to content

Commit df983da

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Record default values of formal parameters.
Fine-grained manifests now capture more information about function and constructor parameters so the analyzer can detect semantically relevant changes. What’s changed - Record the default value of optional named and positional parameters as a `ManifestNode`, and include it in matching/serialization logic. - Track whether a parameter is an initializing formal (`this`) or a super formal (`super`) and persist these flags in manifests. - Add a `never_` entry to `ManifestAstElementKind` and collect `NeverElementImpl` so const initializers that reference `Never` are represented correctly. - Enhance result printing to display `this`/`super` markers, default values, and decode `Never` in element indices. - Bump `AnalysisDriver.DATA_VERSION` to 552 to invalidate stale caches. Why Previously, default parameter values and formal origin (`this`/`super`) were not part of the manifest. Changing them could leave linked data unchanged, producing stale analysis results. By encoding these details (and handling `Never`), we ensure manifest matching reflects the true API surface and triggers re-linking when defaults or formal kinds change. Change-Id: Icae8281f923879574fdc6143fd2c9d6018f4d48f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/449363 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 827551f commit df983da

File tree

5 files changed

+527
-76
lines changed

5 files changed

+527
-76
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 = 550;
109+
static const int DATA_VERSION = 552;
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/fine/manifest_ast.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum ManifestAstElementKind {
2222
dynamic_,
2323
formalParameter,
2424
importPrefix,
25+
never_,
2526
typeParameter,
2627
regular,
2728
multiplyDefined;
@@ -441,6 +442,9 @@ class _ElementCollector extends GeneralizingAstVisitor<void> {
441442
case DynamicElementImpl():
442443
kind = ManifestAstElementKind.dynamic_;
443444
rawIndex = 0;
445+
case NeverElementImpl():
446+
kind = ManifestAstElementKind.never_;
447+
rawIndex = 0;
444448
case MultiplyDefinedElementImpl():
445449
kind = ManifestAstElementKind.multiplyDefined;
446450
rawIndex = 0;

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

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import 'package:analyzer/dart/element/nullability_suffix.dart';
99
import 'package:analyzer/dart/element/type.dart';
1010
import 'package:analyzer/src/binary/binary_reader.dart';
1111
import 'package:analyzer/src/binary/binary_writer.dart';
12+
import 'package:analyzer/src/dart/ast/ast.dart';
1213
import 'package:analyzer/src/dart/element/element.dart';
1314
import 'package:analyzer/src/dart/element/type.dart';
15+
import 'package:analyzer/src/fine/manifest_ast.dart';
1416
import 'package:analyzer/src/fine/manifest_context.dart';
1517
import 'package:analyzer/src/fine/manifest_item.dart';
1618
import 'package:analyzer/src/utilities/extensions/collection.dart';
@@ -35,14 +37,40 @@ sealed class ManifestFunctionFormalParameter {
3537
final ManifestMetadata metadata;
3638
final bool isRequired;
3739
final bool isCovariant;
40+
final bool isInitializingFormal;
41+
final bool isSuperFormal;
3842
final ManifestType type;
43+
final ManifestNode? defaultValue;
3944

4045
ManifestFunctionFormalParameter({
4146
required this.metadata,
4247
required this.isRequired,
4348
required this.isCovariant,
49+
required this.isInitializingFormal,
50+
required this.isSuperFormal,
4451
required this.type,
52+
required this.defaultValue,
4553
});
54+
55+
bool match(MatchContext context, InternalFormalParameterElement element) {
56+
return metadata.match(context, element.metadata) &&
57+
element.isRequired == isRequired &&
58+
element.isCovariant == isCovariant &&
59+
element.isInitializingFormal == isInitializingFormal &&
60+
element.isSuperFormal == isSuperFormal &&
61+
type.match(context, element.type) &&
62+
defaultValue.match(context, element.constantInitializer);
63+
}
64+
65+
void write(BufferedSink sink) {
66+
metadata.write(sink);
67+
sink.writeBool(isRequired);
68+
sink.writeBool(isCovariant);
69+
sink.writeBool(isInitializingFormal);
70+
sink.writeBool(isSuperFormal);
71+
type.write(sink);
72+
defaultValue.writeOptional(sink);
73+
}
4674
}
4775

4876
class ManifestFunctionNamedFormalParameter
@@ -57,7 +85,10 @@ class ManifestFunctionNamedFormalParameter
5785
metadata: ManifestMetadata.encode(context, element.metadata),
5886
isRequired: element.isRequired,
5987
isCovariant: element.isCovariant,
88+
isInitializingFormal: element.isInitializingFormal,
89+
isSuperFormal: element.isSuperFormal,
6090
type: element.type.encode(context),
91+
defaultValue: element.constantInitializer?.encode(context),
6192
name: element.name ?? '',
6293
);
6394
}
@@ -67,7 +98,10 @@ class ManifestFunctionNamedFormalParameter
6798
metadata: ManifestMetadata.read(reader),
6899
isRequired: reader.readBool(),
69100
isCovariant: reader.readBool(),
101+
isInitializingFormal: reader.readBool(),
102+
isSuperFormal: reader.readBool(),
70103
type: ManifestType.read(reader),
104+
defaultValue: ManifestNode.readOptional(reader),
71105
name: reader.readStringUtf8(),
72106
);
73107
}
@@ -76,24 +110,23 @@ class ManifestFunctionNamedFormalParameter
76110
required super.metadata,
77111
required super.isRequired,
78112
required super.isCovariant,
113+
required super.isInitializingFormal,
114+
required super.isSuperFormal,
79115
required super.type,
116+
required super.defaultValue,
80117
required this.name,
81118
});
82119

120+
@override
83121
bool match(MatchContext context, InternalFormalParameterElement element) {
84122
return element.isNamed &&
85-
metadata.match(context, element.metadata) &&
86-
element.isRequired == isRequired &&
87-
element.isCovariant == isCovariant &&
88-
type.match(context, element.type) &&
123+
super.match(context, element) &&
89124
element.name == name;
90125
}
91126

127+
@override
92128
void write(BufferedSink sink) {
93-
metadata.write(sink);
94-
sink.writeBool(isRequired);
95-
sink.writeBool(isCovariant);
96-
type.write(sink);
129+
super.write(sink);
97130
sink.writeStringUtf8(name);
98131
}
99132
}
@@ -108,7 +141,10 @@ class ManifestFunctionPositionalFormalParameter
108141
metadata: ManifestMetadata.encode(context, element.metadata),
109142
isRequired: element.isRequiredPositional,
110143
isCovariant: element.isCovariant,
144+
isInitializingFormal: element.isInitializingFormal,
145+
isSuperFormal: element.isSuperFormal,
111146
type: element.type.encode(context),
147+
defaultValue: element.constantInitializer?.encode(context),
112148
);
113149
}
114150

@@ -119,30 +155,26 @@ class ManifestFunctionPositionalFormalParameter
119155
metadata: ManifestMetadata.read(reader),
120156
isRequired: reader.readBool(),
121157
isCovariant: reader.readBool(),
158+
isInitializingFormal: reader.readBool(),
159+
isSuperFormal: reader.readBool(),
122160
type: ManifestType.read(reader),
161+
defaultValue: ManifestNode.readOptional(reader),
123162
);
124163
}
125164

126165
ManifestFunctionPositionalFormalParameter._({
127166
required super.metadata,
128167
required super.isRequired,
129168
required super.isCovariant,
169+
required super.isInitializingFormal,
170+
required super.isSuperFormal,
130171
required super.type,
172+
required super.defaultValue,
131173
});
132174

175+
@override
133176
bool match(MatchContext context, InternalFormalParameterElement element) {
134-
return element.isPositional &&
135-
metadata.match(context, element.metadata) &&
136-
element.isRequired == isRequired &&
137-
element.isCovariant == isCovariant &&
138-
type.match(context, element.type);
139-
}
140-
141-
void write(BufferedSink sink) {
142-
metadata.write(sink);
143-
sink.writeBool(isRequired);
144-
sink.writeBool(isCovariant);
145-
type.write(sink);
177+
return element.isPositional && super.match(context, element);
146178
}
147179
}
148180

@@ -742,3 +774,9 @@ extension ManifestTypeOrNullExtension on ManifestType? {
742774
sink.writeOptionalObject(this, (x) => x.write(sink));
743775
}
744776
}
777+
778+
extension _AstNodeExtension on AstNode {
779+
ManifestNode encode(EncodeContext context) {
780+
return ManifestNode.encode(context, this);
781+
}
782+
}

0 commit comments

Comments
 (0)