Fine. Store formal parameter default values separately from FunctionType(s).

A type is just a type, it should not attempt to carry element semantics.

Bug: https://github.com/dart-lang/sdk/issues/63555
Change-Id: I9dacc4f5cc4060d862f7e1bb1ececdd9dc1a303c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510420
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov
2026-06-10 10:29:28 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 8f1a38f07b
commit 6d86b39595
6 changed files with 116 additions and 27 deletions
@@ -109,7 +109,7 @@ testFineAfterLibraryAnalyzerHook;
// TODO(scheglov): Clean up the list of implicitly analyzed files.
class AnalysisDriver {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 638;
static const int DATA_VERSION = 639;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
@@ -203,6 +203,10 @@ class ManifestNode {
return reader.readTypedList(() => ManifestNode.read(reader));
}
static List<ManifestNode?> readListOfOptional(BinaryReader reader) {
return reader.readTypedList(() => ManifestNode.readOptional(reader));
}
static ManifestNode? readOptional(BinaryReader reader) {
return reader.readOptionalObject(() => ManifestNode.read(reader));
}
@@ -529,6 +533,26 @@ extension ListOfManifestNodeExtension on List<ManifestNode> {
}
}
extension ListOfManifestNodeOrNullExtension on List<ManifestNode?> {
bool match(MatchContext context, List<AstNode?> nodes) {
if (nodes.length != length) {
return false;
}
for (var i = 0; i < length; i++) {
if (!this[i].match(context, nodes[i])) {
return false;
}
}
return true;
}
void writeList(BinaryWriter writer) {
writer.writeList(this, (node) {
node.writeOptional(writer);
});
}
}
extension ManifestNodeOrNullExtension on ManifestNode? {
bool match(MatchContext context, AstNode? node) {
var self = this;
+37 -1
View File
@@ -132,6 +132,7 @@ class ConstructorItem extends ExecutableItem<ConstructorElementImpl> {
required _ConstructorItemFlags super.flags,
required super.metadata,
required super.functionType,
required super.formalParameterDefaultValues,
required this.constantInitializers,
required this.redirectedConstructor,
required this.superConstructor,
@@ -148,6 +149,8 @@ class ConstructorItem extends ExecutableItem<ConstructorElementImpl> {
flags: _ConstructorItemFlags.encode(element),
metadata: ManifestMetadata.encode(context, element.metadata),
functionType: element.type.encode(context),
formalParameterDefaultValues: element.formalParameters
.encodeDefaultValues(context),
constantInitializers: element.constantInitializers
.map((initializer) => ManifestNode.encode(context, initializer))
.toFixedList(),
@@ -169,6 +172,7 @@ class ConstructorItem extends ExecutableItem<ConstructorElementImpl> {
flags: _ConstructorItemFlags.read(reader),
metadata: ManifestMetadata.read(reader),
functionType: ManifestFunctionType.read(reader),
formalParameterDefaultValues: ManifestNode.readListOfOptional(reader),
constantInitializers: ManifestNode.readList(reader),
redirectedConstructor: ManifestElement.readOptional(reader),
superConstructor: ManifestElement.readOptional(reader),
@@ -284,12 +288,14 @@ class EnumItem extends InterfaceItem<EnumElementImpl> {
sealed class ExecutableItem<E extends ExecutableElementImpl>
extends ManifestItem<E> {
final ManifestFunctionType functionType;
final List<ManifestNode?> formalParameterDefaultValues;
ExecutableItem({
required super.id,
required _ExecutableItemFlags super.flags,
required super.metadata,
required this.functionType,
required this.formalParameterDefaultValues,
});
@override
@@ -307,13 +313,18 @@ sealed class ExecutableItem<E extends ExecutableElementImpl>
flags.isExternal == element.isExternal &&
flags.isSimplyBounded == element.isSimplyBounded &&
flags.isStatic == element.isStatic &&
functionType.match(context, element.type);
functionType.match(context, element.type) &&
formalParameterDefaultValues.match(
context,
element.formalParameters.map((e) => e.constantInitializer).toList(),
);
}
@override
void write(BinaryWriter writer) {
super.write(writer);
functionType.writeNoTag(writer);
formalParameterDefaultValues.writeList(writer);
}
}
@@ -564,6 +575,7 @@ class GetterItem extends PropertyAccessorItem<GetterElementImpl> {
required super.flags,
required super.metadata,
required super.functionType,
required super.formalParameterDefaultValues,
});
factory GetterItem.fromElement({
@@ -579,6 +591,8 @@ class GetterItem extends PropertyAccessorItem<GetterElementImpl> {
element.thisOrVariableMetadata,
),
functionType: element.type.encode(context),
formalParameterDefaultValues: element.formalParameters
.encodeDefaultValues(context),
);
}
@@ -588,6 +602,7 @@ class GetterItem extends PropertyAccessorItem<GetterElementImpl> {
flags: _PropertyAccessorItemFlags.read(reader),
metadata: ManifestMetadata.read(reader),
functionType: ManifestFunctionType.read(reader),
formalParameterDefaultValues: ManifestNode.readListOfOptional(reader),
);
}
@@ -1226,6 +1241,7 @@ class MethodItem extends ExecutableItem<MethodElementImpl> {
required _MethodItemFlags super.flags,
required super.metadata,
required super.functionType,
required super.formalParameterDefaultValues,
required this.typeInferenceError,
});
@@ -1239,6 +1255,8 @@ class MethodItem extends ExecutableItem<MethodElementImpl> {
flags: _MethodItemFlags.encode(element),
metadata: ManifestMetadata.encode(context, element.metadata),
functionType: element.type.encode(context),
formalParameterDefaultValues: element.formalParameters
.encodeDefaultValues(context),
typeInferenceError: element.typeInferenceError,
);
}
@@ -1249,6 +1267,7 @@ class MethodItem extends ExecutableItem<MethodElementImpl> {
flags: _MethodItemFlags.read(reader),
metadata: ManifestMetadata.read(reader),
functionType: ManifestFunctionType.read(reader),
formalParameterDefaultValues: ManifestNode.readListOfOptional(reader),
typeInferenceError: TopLevelInferenceError.readOptional(reader),
);
}
@@ -1390,6 +1409,7 @@ sealed class PropertyAccessorItem<E extends PropertyAccessorElementImpl>
required _PropertyAccessorItemFlags super.flags,
required super.metadata,
required super.functionType,
required super.formalParameterDefaultValues,
});
@override
@@ -1411,6 +1431,7 @@ class SetterItem extends PropertyAccessorItem<SetterElementImpl> {
required super.flags,
required super.metadata,
required super.functionType,
required super.formalParameterDefaultValues,
});
factory SetterItem.fromElement({
@@ -1426,6 +1447,8 @@ class SetterItem extends PropertyAccessorItem<SetterElementImpl> {
element.thisOrVariableMetadata,
),
functionType: element.type.encode(context),
formalParameterDefaultValues: element.formalParameters
.encodeDefaultValues(context),
);
}
@@ -1435,6 +1458,7 @@ class SetterItem extends PropertyAccessorItem<SetterElementImpl> {
flags: _PropertyAccessorItemFlags.read(reader),
metadata: ManifestMetadata.read(reader),
functionType: ManifestFunctionType.read(reader),
formalParameterDefaultValues: ManifestNode.readListOfOptional(reader),
);
}
@@ -1452,6 +1476,7 @@ class TopLevelFunctionItem extends ExecutableItem<TopLevelFunctionElementImpl> {
required _TopLevelFunctionItemFlags super.flags,
required super.metadata,
required super.functionType,
required super.formalParameterDefaultValues,
});
factory TopLevelFunctionItem.fromElement({
@@ -1464,6 +1489,8 @@ class TopLevelFunctionItem extends ExecutableItem<TopLevelFunctionElementImpl> {
flags: _TopLevelFunctionItemFlags.encode(element),
metadata: ManifestMetadata.encode(context, element.metadata),
functionType: element.type.encode(context),
formalParameterDefaultValues: element.formalParameters
.encodeDefaultValues(context),
);
}
@@ -1473,6 +1500,7 @@ class TopLevelFunctionItem extends ExecutableItem<TopLevelFunctionElementImpl> {
flags: _TopLevelFunctionItemFlags.read(reader),
metadata: ManifestMetadata.read(reader),
functionType: ManifestFunctionType.read(reader),
formalParameterDefaultValues: ManifestNode.readListOfOptional(reader),
);
}
@@ -2548,6 +2576,14 @@ extension type _VariableItemFlags._(int _bits) implements _ManifestItemFlags {
}
}
extension on List<InternalFormalParameterElement> {
List<ManifestNode?> encodeDefaultValues(EncodeContext context) {
return map((element) {
return element.constantInitializer?.encode(context);
}).toFixedList();
}
}
extension BinaryReaderExtension on BinaryReader {
Map<LookupName, V> readLookupNameMap<V>({required V Function() readValue}) {
return readMap(
+1 -19
View File
@@ -9,10 +9,8 @@ import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/binary/binary_reader.dart';
import 'package:analyzer/src/binary/binary_writer.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/fine/manifest_ast.dart';
import 'package:analyzer/src/fine/manifest_context.dart';
import 'package:analyzer/src/fine/manifest_item.dart';
import 'package:analyzer/src/utilities/extensions/collection.dart';
@@ -39,7 +37,6 @@ sealed class ManifestFunctionFormalParameter {
final bool isCovariant;
final FormalParameterDeclarationForm declarationForm;
final ManifestType type;
final ManifestNode? defaultValue;
ManifestFunctionFormalParameter({
required this.metadata,
@@ -47,7 +44,6 @@ sealed class ManifestFunctionFormalParameter {
required this.isCovariant,
required this.declarationForm,
required this.type,
required this.defaultValue,
});
bool match(MatchContext context, InternalFormalParameterElement element) {
@@ -55,8 +51,7 @@ sealed class ManifestFunctionFormalParameter {
element.isRequired == isRequired &&
element.isCovariant == isCovariant &&
element.declarationForm == declarationForm &&
type.match(context, element.type) &&
defaultValue.match(context, element.constantInitializer);
type.match(context, element.type);
}
void write(BinaryWriter writer) {
@@ -65,7 +60,6 @@ sealed class ManifestFunctionFormalParameter {
writer.writeBool(isCovariant);
writer.writeEnum(declarationForm);
type.write(writer);
defaultValue.writeOptional(writer);
}
}
@@ -83,7 +77,6 @@ class ManifestFunctionNamedFormalParameter
isCovariant: element.isCovariant,
declarationForm: element.declarationForm,
type: element.type.encode(context),
defaultValue: element.constantInitializer?.encode(context),
name: element.name ?? '',
);
}
@@ -95,7 +88,6 @@ class ManifestFunctionNamedFormalParameter
isCovariant: reader.readBool(),
declarationForm: reader.readEnum(FormalParameterDeclarationForm.values),
type: ManifestType.read(reader),
defaultValue: ManifestNode.readOptional(reader),
name: reader.readStringReference(),
);
}
@@ -106,7 +98,6 @@ class ManifestFunctionNamedFormalParameter
required super.isCovariant,
required super.declarationForm,
required super.type,
required super.defaultValue,
required this.name,
});
@@ -136,7 +127,6 @@ class ManifestFunctionPositionalFormalParameter
isCovariant: element.isCovariant,
declarationForm: element.declarationForm,
type: element.type.encode(context),
defaultValue: element.constantInitializer?.encode(context),
);
}
@@ -147,7 +137,6 @@ class ManifestFunctionPositionalFormalParameter
isCovariant: reader.readBool(),
declarationForm: reader.readEnum(FormalParameterDeclarationForm.values),
type: ManifestType.read(reader),
defaultValue: ManifestNode.readOptional(reader),
);
}
@@ -157,7 +146,6 @@ class ManifestFunctionPositionalFormalParameter
required super.isCovariant,
required super.declarationForm,
required super.type,
required super.defaultValue,
});
@override
@@ -762,9 +750,3 @@ extension ManifestTypeOrNullExtension on ManifestType? {
writer.writeOptionalObject(this, (x) => x.write(writer));
}
}
extension _AstNodeExtension on AstNode {
ManifestNode encode(EncodeContext context) {
return ManifestNode.encode(context, this);
}
}
@@ -95670,6 +95670,42 @@ final b = 1;
);
}
test_manifest_topLevelVariable_initializer_functionType_defaultValue() async {
await _runLibraryManifestScenario(
initialCode: r'''
final x = ([int a = 0]) => a;
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
hashForRequirements: #H0
declaredGetters
x: #M0
declaredVariables
x: #M1
exportMapId: #M2
exportMap
x: #M0
''',
updatedCode: r'''
final x = ([int a = 1]) => a;
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
hashForRequirements: #H0
declaredGetters
x: #M0
declaredVariables
x: #M1
exportMapId: #M2
exportMap
x: #M0
''',
);
}
test_manifest_topLevelVariable_initializer_type() async {
await _runLibraryManifestScenario(
initialCode: r'''
@@ -1400,6 +1400,17 @@ class LibraryManifestPrinter extends ManifestPrinter {
});
}
void _writeFormalParameterDefaultValues(ExecutableItem item) {
if (configuration.withElementManifests) {
var indexed = item.formalParameterDefaultValues.indexed
.where((entry) => entry.$2 != null)
.toList();
sink.writeElements('formalParameterDefaultValues', indexed, (entry) {
_writeNode('[${entry.$1}]', entry.$2);
});
}
}
void _writeGetterItem(GetterItem item) {
if (configuration.withElementManifests) {
sink.withIndent(() {
@@ -1411,6 +1422,7 @@ class LibraryManifestPrinter extends ManifestPrinter {
});
_writeMetadata(item);
_writeNamedType('returnType', item.functionType.returnType);
_writeFormalParameterDefaultValues(item);
});
}
}
@@ -1485,6 +1497,7 @@ class LibraryManifestPrinter extends ManifestPrinter {
});
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
_writeFormalParameterDefaultValues(item);
});
writeDeclaredItems('declaredMethods', item.declaredMethods, (item) {
@@ -1497,6 +1510,7 @@ class LibraryManifestPrinter extends ManifestPrinter {
});
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
_writeFormalParameterDefaultValues(item);
_writeTopLevelInferenceError('inferenceError', item.typeInferenceError);
});
@@ -1515,6 +1529,7 @@ class LibraryManifestPrinter extends ManifestPrinter {
});
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
_writeFormalParameterDefaultValues(item);
_writelnNamedElement(
'redirectedConstructor',
item.redirectedConstructor,
@@ -1744,6 +1759,7 @@ class LibraryManifestPrinter extends ManifestPrinter {
});
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
_writeFormalParameterDefaultValues(item);
});
}
}
@@ -1758,6 +1774,7 @@ class LibraryManifestPrinter extends ManifestPrinter {
});
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
_writeFormalParameterDefaultValues(item);
});
}
}
@@ -1830,18 +1847,12 @@ class LibraryManifestPrinter extends ManifestPrinter {
sink.writeIf(field.isRequired, 'required ');
writeParameterDeclarationForm(field);
_writeType(field.type);
sink.withIndent(() {
_writeNode('defaultValue', field.defaultValue);
});
});
sink.writeElements('named', type.named, (field) {
sink.writeWithIndent('${field.name}: ');
sink.writeIf(field.isRequired, 'required ');
writeParameterDeclarationForm(field);
_writeType(field.type);
sink.withIndent(() {
_writeNode('defaultValue', field.defaultValue);
});
});
_writeNamedType('returnType', type.returnType);
});