Fine. Support for constructor constantInitializers.
Change-Id: Ib166a4348365053d332287c0a0ca73197909dac4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422025
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/fine/manifest_ast.dart b/pkg/analyzer/lib/src/fine/manifest_ast.dart
index c7e4523..3efc9a6 100644
--- a/pkg/analyzer/lib/src/fine/manifest_ast.dart
+++ b/pkg/analyzer/lib/src/fine/manifest_ast.dart
@@ -136,6 +136,10 @@
sink.writeUint30List(elementIndexList);
}
+ static List<ManifestNode> readList(SummaryDataReader reader) {
+ return reader.readTypedList(() => ManifestNode.read(reader));
+ }
+
static ManifestNode? readOptional(SummaryDataReader reader) {
return reader.readOptionalObject(() => ManifestNode.read(reader));
}
@@ -165,6 +169,11 @@
}
@override
+ void visitAssertInitializer(AssertInitializer node) {
+ node.visitChildren(this);
+ }
+
+ @override
void visitBinaryExpression(BinaryExpression node) {
node.visitChildren(this);
_addElement(node.element);
@@ -174,6 +183,11 @@
void visitBooleanLiteral(BooleanLiteral node) {}
@override
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ node.visitChildren(this);
+ }
+
+ @override
void visitConstructorName(ConstructorName node) {
node.visitChildren(this);
_addElement(node.element);
@@ -265,6 +279,12 @@
}
@override
+ void visitRedirectingConstructorInvocation(
+ RedirectingConstructorInvocation node) {
+ node.visitChildren(this);
+ }
+
+ @override
void visitSetOrMapLiteral(SetOrMapLiteral node) {
node.visitChildren(this);
}
@@ -293,6 +313,11 @@
}
@override
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ node.visitChildren(this);
+ }
+
+ @override
void visitTypeArgumentList(TypeArgumentList node) {
node.visitChildren(this);
}
@@ -310,6 +335,24 @@
}
}
+extension ListOfManifestNodeExtension 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(BufferedSink sink) {
+ sink.writeList(this, (x) => x.write(sink));
+ }
+}
+
extension ManifestNodeOrNullExtension on ManifestNode? {
bool match(MatchContext context, AstNode? node) {
var self = this;
diff --git a/pkg/analyzer/lib/src/fine/manifest_item.dart b/pkg/analyzer/lib/src/fine/manifest_item.dart
index 136b495..52d882e 100644
--- a/pkg/analyzer/lib/src/fine/manifest_item.dart
+++ b/pkg/analyzer/lib/src/fine/manifest_item.dart
@@ -363,6 +363,7 @@
final bool isConst;
final bool isFactory;
final ManifestFunctionType functionType;
+ final List<ManifestNode> constantInitializers;
InterfaceItemConstructorItem({
required super.id,
@@ -371,6 +372,7 @@
required this.isConst,
required this.isFactory,
required this.functionType,
+ required this.constantInitializers,
});
factory InterfaceItemConstructorItem.fromElement({
@@ -378,7 +380,6 @@
required EncodeContext context,
required ConstructorElementImpl2 element,
}) {
- // TODO(scheglov): initializers
return InterfaceItemConstructorItem(
id: id,
metadata: ManifestMetadata.encode(context, element.metadata2),
@@ -386,6 +387,9 @@
isConst: element.isConst,
isFactory: element.isFactory,
functionType: element.type.encode(context),
+ constantInitializers: element.constantInitializers
+ .map((initializer) => ManifestNode.encode(context, initializer))
+ .toFixedList(),
);
}
@@ -397,6 +401,7 @@
isConst: reader.readBool(),
isFactory: reader.readBool(),
functionType: ManifestFunctionType.read(reader),
+ constantInitializers: ManifestNode.readList(reader),
);
}
@@ -405,7 +410,8 @@
return super.match(context, element) &&
isConst == element.isConst &&
isFactory == element.isFactory &&
- functionType.match(context, element.type);
+ functionType.match(context, element.type) &&
+ constantInitializers.match(context, element.constantInitializers);
}
@override
@@ -415,6 +421,7 @@
sink.writeBool(isConst);
sink.writeBool(isFactory);
functionType.writeNoTag(sink);
+ constantInitializers.writeList(sink);
}
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 9575945..d97ba7f 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -12390,6 +12390,570 @@
);
}
+ test_manifest_class_constructor_initializers_isConst_add() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ const A.named(int x);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+''',
+ updatedCode: r'''
+class A {
+ const A.named(int x) : assert(x > 0);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M2
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_assert() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ const A.named(int x) : assert(x > 0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+''',
+ updatedCode: r'''
+class A {
+ const A.named(int x) : assert(x > 1);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M2
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_fieldInitializer_name() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int foo;
+ const A.named() : bar = 0;
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ foo: #M1
+ named: #M2
+''',
+ updatedCode: r'''
+class A {
+ final int foo;
+ const A.named() : foo = 0;
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ foo: #M1
+ named: #M3
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_fieldInitializer_value() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int foo;
+ const A.named() : foo = 0;
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ foo: #M1
+ named: #M2
+''',
+ updatedCode: r'''
+class A {
+ final int foo;
+ const A.named() : foo = 1;
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ foo: #M1
+ named: #M3
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_redirect_argument() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int f;
+ const A.c1(int a) : f = a;
+ const A.c2() : this.c1(0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M2
+ f: #M3
+''',
+ updatedCode: r'''
+class A {
+ final int f;
+ const A.c1(int a) : f = a;
+ const A.c2() : this.c1(1);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M4
+ f: #M3
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_redirect_name() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int f;
+ const A.c1() : f = 0;
+ const A.c2() : f = 1;
+ const A.c3() : this.c1();
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M2
+ c3: #M3
+ f: #M4
+''',
+ updatedCode: r'''
+class A {
+ final int f;
+ const A.c1() : f = 0;
+ const A.c2() : f = 1;
+ const A.c3() : this.c2();
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M2
+ c3: #M5
+ f: #M4
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_remove() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ const A.named(int x) : assert(x > 0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+''',
+ updatedCode: r'''
+class A {
+ const A.named(int x);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M2
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_super_argument() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ const A.named(int _);
+}
+
+class B extends A {
+ const A.named() : super.named(0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+ B: #M2
+ declaredMembers
+ named: #M3
+''',
+ updatedCode: r'''
+class A {
+ const A.named(int _);
+}
+
+class B extends A {
+ const A.named() : super.named(1);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+ B: #M2
+ declaredMembers
+ named: #M4
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_super_name() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int f;
+ const A.c1() : f = 0;
+ const A.c2() : f = 1;
+}
+
+class B extends A {
+ const A.named() : super.c1(0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M2
+ f: #M3
+ B: #M4
+ declaredMembers
+ named: #M5
+ inheritedMembers
+ f: #M3
+''',
+ updatedCode: r'''
+class A {
+ final int f;
+ const A.c1() : f = 0;
+ const A.c2() : f = 1;
+}
+
+class B extends A {
+ const A.named() : super.c2(0);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M2
+ f: #M3
+ B: #M4
+ declaredMembers
+ named: #M6
+ inheritedMembers
+ f: #M3
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_isConst_super_transitive() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int f;
+ const A.named() : f = 0;
+}
+
+class B extends A {
+ const A.named() : super.named();
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ f: #M1
+ named: #M2
+ B: #M3
+ declaredMembers
+ named: #M4
+ inheritedMembers
+ f: #M1
+''',
+ updatedCode: r'''
+class A {
+ final int f;
+ const A.named() : f = 1;
+}
+
+class B extends A {
+ const A.named() : super.named();
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ f: #M1
+ named: #M5
+ B: #M3
+ declaredMembers
+ named: #M6
+ inheritedMembers
+ f: #M1
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_notConst_assert() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ A.named(int x) : assert(x > 0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+''',
+ updatedCode: r'''
+class A {
+ A.named(int x) : assert(x > 1);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_notConst_fieldInitializer_value() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int foo;
+ A.named() : foo = 0;
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ foo: #M1
+ named: #M2
+''',
+ updatedCode: r'''
+class A {
+ final int foo;
+ A.named() : foo = 1;
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ foo: #M1
+ named: #M2
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_notConst_redirect_argument() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ final int f;
+ A.c1(int a) : f = a;
+ A.c2() : this.c1(0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M2
+ f: #M3
+''',
+ updatedCode: r'''
+class A {
+ final int f;
+ A.c1(int a) : f = a;
+ A.c2() : this.c1(1);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ c1: #M1
+ c2: #M2
+ f: #M3
+''',
+ );
+ }
+
+ test_manifest_class_constructor_initializers_notConst_super_argument() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ const A.named(int _);
+}
+
+class B extends A {
+ A.named() : super.named(0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+ B: #M2
+ declaredMembers
+ named: #M3
+''',
+ updatedCode: r'''
+class A {
+ const A.named(int _);
+}
+
+class B extends A {
+ A.named() : super.named(1);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ manifest
+ A: #M0
+ declaredMembers
+ named: #M1
+ B: #M2
+ declaredMembers
+ named: #M3
+''',
+ );
+ }
+
test_manifest_class_constructor_isConst_falseToTrue() async {
await _runLibraryManifestScenario(
initialCode: r'''