Fine. Support for setters in InstanceElement(s).

Change-Id: I7f55cbb4fb49bcf5d83053de599b43dfb3b6c434
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421880
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov
2025-04-10 10:32:15 -07:00
committed by Commit Queue
parent 717257b065
commit d9f850f74e
4 changed files with 670 additions and 8 deletions
@@ -228,7 +228,12 @@ class LibraryManifestBuilder {
instanceItem: instanceItem,
element: element,
);
// TODO(scheglov): add setters support
case SetterElement2OrMember():
_addInstanceElementSetter(
encodingContext: encodingContext,
instanceItem: instanceItem,
element: element,
);
}
}
@@ -252,6 +257,26 @@ class LibraryManifestBuilder {
instanceItem.declaredMembers[lookupName] = item;
}
void _addInstanceElementSetter({
required EncodeContext encodingContext,
required InstanceItem instanceItem,
required SetterElement2OrMember element,
}) {
var lookupName = element.lookupName?.asLookupName;
if (lookupName == null) {
return;
}
var item = _getOrBuildElementItem(element, () {
return InstanceItemSetterItem.fromElement(
id: ManifestItemId.generate(),
context: encodingContext,
element: element,
);
});
instanceItem.declaredMembers[lookupName] = item;
}
void _addInstanceElementStaticExecutables({
required EncodeContext encodingContext,
required InstanceElementImpl2 instanceElement,
@@ -276,6 +301,16 @@ class LibraryManifestBuilder {
);
}
}
for (var getter in instanceElement.setters2) {
if (getter.isStatic) {
_addInstanceElementSetter(
encodingContext: encodingContext,
instanceItem: instanceItem,
element: getter,
);
}
}
}
void _addInterfaceElementConstructor({
@@ -762,7 +797,18 @@ class _LibraryMatch {
refExternalIds.addAll(matchContext.externalIds);
return true;
case SetterElement2OrMember():
// TODO(scheglov): implement
if (item is! InstanceItemSetterItem) {
return false;
}
var matchContext = MatchContext(parent: interfaceMatchContext);
if (!item.match(matchContext, executable)) {
return false;
}
itemMap[executable] = item;
refElementsMap[executable] = matchContext.elementList;
refExternalIds.addAll(matchContext.externalIds);
return true;
}
@@ -843,17 +889,17 @@ class _LibraryMatch {
}) {
// TODO(scheglov): it looks that we repeat iterations
// We do it for structural matching, and then for adding.
for (var getters in element.getters2) {
if (getters.isStatic) {
var lookupName = getters.name3?.asLookupName;
for (var getter in element.getters2) {
if (getter.isStatic) {
var lookupName = getter.lookupName?.asLookupName;
if (lookupName != null) {
if (!_matchInstanceExecutable(
interfaceMatchContext: matchContext,
members: item.declaredMembers,
lookupName: lookupName,
executable: getters,
executable: getter,
)) {
structureMismatched.add(getters);
structureMismatched.add(getter);
}
}
}
@@ -861,7 +907,7 @@ class _LibraryMatch {
for (var method in element.methods2) {
if (method.isStatic) {
var lookupName = method.name3?.asLookupName;
var lookupName = method.lookupName?.asLookupName;
if (lookupName != null) {
if (!_matchInstanceExecutable(
interfaceMatchContext: matchContext,
@@ -874,6 +920,22 @@ class _LibraryMatch {
}
}
}
for (var setter in element.setters2) {
if (setter.isStatic) {
var lookupName = setter.lookupName?.asLookupName;
if (lookupName != null) {
if (!_matchInstanceExecutable(
interfaceMatchContext: matchContext,
members: item.declaredMembers,
lookupName: lookupName,
executable: setter,
)) {
structureMismatched.add(setter);
}
}
}
}
}
bool _matchTopFunction({
@@ -170,6 +170,8 @@ sealed class InstanceItemMemberItem extends ManifestItem {
return InstanceItemGetterItem.read(reader);
case _ManifestItemKind2.instanceMethod:
return InstanceItemMethodItem.read(reader);
case _ManifestItemKind2.instanceSetter:
return InstanceItemSetterItem.read(reader);
case _ManifestItemKind2.interfaceConstructor:
return InterfaceItemConstructorItem.read(reader);
}
@@ -239,6 +241,55 @@ class InstanceItemMethodItem extends InstanceItemMemberItem {
}
}
class InstanceItemSetterItem extends InstanceItemMemberItem {
final ManifestType valueType;
InstanceItemSetterItem({
required super.id,
required super.metadata,
required super.isStatic,
required this.valueType,
});
factory InstanceItemSetterItem.fromElement({
required ManifestItemId id,
required EncodeContext context,
required SetterElement2OrMember element,
}) {
return InstanceItemSetterItem(
id: id,
metadata: ManifestMetadata.encode(context, element.metadata2),
isStatic: element.isStatic,
valueType: element.formalParameters[0].type.encode(context),
);
}
factory InstanceItemSetterItem.read(SummaryDataReader reader) {
return InstanceItemSetterItem(
id: ManifestItemId.read(reader),
metadata: ManifestMetadata.read(reader),
isStatic: reader.readBool(),
valueType: ManifestType.read(reader),
);
}
@override
bool match(
MatchContext context,
covariant SetterElement2OrMember element,
) {
return super.match(context, element) &&
valueType.match(context, element.formalParameters[0].type);
}
@override
void write(BufferedSink sink) {
sink.writeEnum(_ManifestItemKind2.instanceSetter);
super.write(sink);
valueType.write(sink);
}
}
/// The item for [InterfaceElementImpl2].
sealed class InterfaceItem extends InstanceItem {
final ManifestType? supertype;
@@ -644,6 +695,7 @@ enum _ManifestItemKind {
enum _ManifestItemKind2 {
instanceGetter,
instanceMethod,
instanceSetter,
interfaceConstructor,
}
@@ -11052,6 +11052,551 @@ class A {}
);
}
test_manifest_class_setter_add_extends() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
set foo(int _) {}
}
class B extends A {}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
B: #M2
inheritedMembers
foo=: #M1
''',
updatedCode: r'''
class A {
set foo(int _) {}
set bar(int _) {}
}
class B extends A {}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M3
foo=: #M1
B: #M2
inheritedMembers
bar=: #M3
foo=: #M1
''',
);
}
test_manifest_class_setter_add_extends_generic() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A<T> {
set foo(T _) {}
}
class B extends A<int> {}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
B: #M2
inheritedMembers
foo=: #M1
''',
updatedCode: r'''
class A<T> {
set foo(T _) {}
set bar(T _) {}
}
class B extends A<int> {}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M3
foo=: #M1
B: #M2
inheritedMembers
bar=: #M3
foo=: #M1
''',
);
}
test_manifest_class_setter_add_implements() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
set foo(int _) {}
}
class B implements A {}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
B: #M2
inheritedMembers
foo=: #M1
''',
updatedCode: r'''
class A {
set foo(int _) {}
set bar(int _) {}
}
class B implements A {}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M3
foo=: #M1
B: #M2
inheritedMembers
bar=: #M3
foo=: #M1
''',
);
}
test_manifest_class_setter_add_implements_generic() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A<T> {
set foo(T _) {}
}
class B implements A<int> {}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
B: #M2
inheritedMembers
foo=: #M1
''',
updatedCode: r'''
class A<T> {
set foo(T _) {}
set bar(T _) {}
}
class B implements A<int> {}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M3
foo=: #M1
B: #M2
inheritedMembers
bar=: #M3
foo=: #M1
''',
);
}
test_manifest_class_setter_add_with() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
set foo(int _) {}
}
class B with A {}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
B: #M2
inheritedMembers
foo=: #M1
''',
updatedCode: r'''
class A {
set foo(int _) {}
set bar(int _) {}
}
class B with A {}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M3
foo=: #M1
B: #M2
inheritedMembers
bar=: #M3
foo=: #M1
''',
);
}
test_manifest_class_setter_add_with_generic() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A<T> {
set foo(T _) {}
}
class B with A<int> {}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
B: #M2
inheritedMembers
foo=: #M1
''',
updatedCode: r'''
class A<T> {
set foo(T _) {}
set bar(T _) {}
}
class B with A<int> {}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M3
foo=: #M1
B: #M2
inheritedMembers
bar=: #M3
foo=: #M1
''',
);
}
test_manifest_class_setter_metadata() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
@Deprecated('0')
set foo(int _) {}
@Deprecated('0')
set bar(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M1
foo=: #M2
''',
updatedCode: r'''
class A {
@Deprecated('1')
set foo(int _) {}
@Deprecated('0')
set bar(int _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M1
foo=: #M3
''',
);
}
test_manifest_class_setter_private_instance() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
set _foo(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
_foo=: #M1
''',
updatedCode: r'''
class A {
set _foo(int _) {}
set bar(int _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
_foo=: #M1
bar=: #M2
''',
);
}
test_manifest_class_setter_private_static() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
static set _foo(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
_foo=: #M1
''',
updatedCode: r'''
class A {
static set _foo(int _) {}
set bar(int _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
_foo=: #M1
bar=: #M2
''',
);
}
test_manifest_class_setter_static() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
static set foo(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
''',
updatedCode: r'''
class A {
static set foo(int _) {}
static set bar(int _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
bar=: #M2
foo=: #M1
''',
);
}
test_manifest_class_setter_static_falseToTrue() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
set foo(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
''',
updatedCode: r'''
class A {
static set foo(int _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M2
''',
);
}
test_manifest_class_setter_static_trueToFalse() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
static set foo(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
''',
updatedCode: r'''
class A {
set foo(int _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M2
''',
);
}
test_manifest_class_setter_static_valueType() async {
await _runLibraryManifestScenario(
initialCode: r'''
class A {
static set foo(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M1
''',
updatedCode: r'''
class A {
static set foo(double _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
declaredMembers
foo=: #M2
''',
);
}
test_manifest_class_setter_valueType() async {
configuration.withElementManifests = true;
await _runLibraryManifestScenario(
initialCode: r'''
class A {
set foo(int _) {}
}
''',
expectedInitialEvents: r'''
[operation] linkLibraryCycle SDK
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
supertype: Object @ dart:core
declaredMembers
foo=: #M1
valueType: int @ dart:core
''',
updatedCode: r'''
class A {
set foo(double _) {}
}
''',
expectedUpdatedEvents: r'''
[operation] linkLibraryCycle
package:test/test.dart
manifest
A: #M0
supertype: Object @ dart:core
declaredMembers
foo=: #M2
valueType: double @ dart:core
''',
);
}
test_manifest_constInitializer_adjacentStrings() async {
await _runLibraryManifestScenario(
initialCode: r'''
@@ -822,6 +822,9 @@ class LibraryManifestPrinter {
case InstanceItemMethodItem():
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
case InstanceItemSetterItem():
_writeMetadata(item);
_writeNamedType('valueType', item.valueType);
case InterfaceItemConstructorItem():
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);