Fine. Record and match metadata for top-level and members. Change-Id: I5462888530294394383462b17c3039a54a16a2ae Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420461 Reviewed-by: Paul Berry <paulberry@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 716992e..e26eada 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -3028,7 +3028,7 @@ _metadata = metadata; } - Metadata get metadata2 => MetadataImpl(_getMetadataFlags(), metadata); + MetadataImpl get metadata2 => MetadataImpl(_getMetadataFlags(), metadata); @override String? get name => _name; @@ -3613,6 +3613,9 @@ List<FormalParameterElementMixin> get formalParameters; @override + MetadataImpl get metadata2; + + @override TypeImpl get returnType; @override @@ -5787,7 +5790,7 @@ LibraryElementImpl get library2 => firstFragment.library; @override - Metadata get metadata2 => firstFragment.metadata2; + MetadataImpl get metadata2 => firstFragment.metadata2; @override List<MethodElementImpl2> get methods2 { @@ -7799,7 +7802,7 @@ bool get isStatic => _wrappedElement.isStatic; @override - Metadata get metadata2 => _wrappedElement.metadata2; + MetadataImpl get metadata2 => _wrappedElement.metadata2; @override TypeImpl get returnType => _wrappedElement.returnType; @@ -10341,6 +10344,9 @@ GetterElement2OrMember? get getter2; @override + MetadataImpl get metadata2; + + @override SetterElement2OrMember? get setter2; }
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart index 6821861..0b17580 100644 --- a/pkg/analyzer/lib/src/dart/element/member.dart +++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -942,7 +942,7 @@ @override List<ElementAnnotation> get metadata => _declaration.metadata; - Metadata get metadata2 => declaration.metadata2; + MetadataImpl get metadata2 => declaration.metadata2; @override String? get name => _declaration.name;
diff --git a/pkg/analyzer/lib/src/fine/library_manifest.dart b/pkg/analyzer/lib/src/fine/library_manifest.dart index 33e5c92..438245a 100644 --- a/pkg/analyzer/lib/src/fine/library_manifest.dart +++ b/pkg/analyzer/lib/src/fine/library_manifest.dart
@@ -309,6 +309,9 @@ } manifest.items[name] = ExportItem( id: id, + // TODO(scheglov): Exports should not be items at all. + // We should have a separate map of names to IDs. + metadata: ManifestMetadata(annotations: []), ); } }
diff --git a/pkg/analyzer/lib/src/fine/manifest_item.dart b/pkg/analyzer/lib/src/fine/manifest_item.dart index 153a7d8..a20041e 100644 --- a/pkg/analyzer/lib/src/fine/manifest_item.dart +++ b/pkg/analyzer/lib/src/fine/manifest_item.dart
@@ -13,9 +13,26 @@ import 'package:analyzer/src/summary2/data_writer.dart'; import 'package:analyzer/src/utilities/extensions/collection.dart'; +// TODO(scheglov): inline into ManifestItem when remove ExportItem +sealed class AnnotatedItem extends ManifestItem { + final ManifestMetadata metadata; + + AnnotatedItem({ + required super.id, + required this.metadata, + }); + + @override + void write(BufferedSink sink) { + super.write(sink); + metadata.write(sink); + } +} + class ClassItem extends InterfaceItem { ClassItem({ required super.id, + required super.metadata, required super.typeParameters, required super.supertype, required super.interfaces, @@ -33,6 +50,7 @@ (typeParameters) { return ClassItem( id: id, + metadata: ManifestMetadata.encode(context, element.metadata2), typeParameters: typeParameters, supertype: element.supertype?.encode(context), mixins: element.mixins.encode(context), @@ -46,6 +64,7 @@ factory ClassItem.read(SummaryDataReader reader) { return ClassItem( id: ManifestItemId.read(reader), + metadata: ManifestMetadata.read(reader), typeParameters: ManifestTypeParameter.readList(reader), members: InstanceItem._readMembers(reader), supertype: ManifestType.readOptional(reader), @@ -68,11 +87,13 @@ class ExportItem extends TopLevelItem { ExportItem({ required super.id, + required super.metadata, }); factory ExportItem.read(SummaryDataReader reader) { return ExportItem( id: ManifestItemId.read(reader), + metadata: ManifestMetadata.read(reader), ); } @@ -90,6 +111,7 @@ InstanceItem({ required super.id, + required super.metadata, required this.typeParameters, required this.members, }); @@ -120,6 +142,7 @@ InstanceItemGetterItem({ required super.id, + required super.metadata, required super.isStatic, required this.returnType, }); @@ -131,6 +154,7 @@ }) { return InstanceItemGetterItem( id: id, + metadata: ManifestMetadata.encode(context, element.metadata2), isStatic: element.isStatic, returnType: element.returnType.encode(context), ); @@ -139,6 +163,7 @@ factory InstanceItemGetterItem.read(SummaryDataReader reader) { return InstanceItemGetterItem( id: ManifestItemId.read(reader), + metadata: ManifestMetadata.read(reader), isStatic: reader.readBool(), returnType: ManifestType.read(reader), ); @@ -149,6 +174,9 @@ GetterElement2OrMember element, ) { var context = MatchContext(parent: instanceContext); + if (!metadata.match(context, element.metadata2)) { + return null; + } if (element.isStatic != isStatic) { return null; } @@ -166,11 +194,12 @@ } } -sealed class InstanceItemMemberItem extends ManifestItem { +sealed class InstanceItemMemberItem extends AnnotatedItem { final bool isStatic; InstanceItemMemberItem({ required super.id, + required super.metadata, required this.isStatic, }); @@ -198,6 +227,7 @@ InstanceItemMethodItem({ required super.id, + required super.metadata, required super.isStatic, required this.functionType, }); @@ -209,6 +239,7 @@ }) { return InstanceItemMethodItem( id: id, + metadata: ManifestMetadata.encode(context, element.metadata2), isStatic: element.isStatic, functionType: element.type.encode(context), ); @@ -217,6 +248,7 @@ factory InstanceItemMethodItem.read(SummaryDataReader reader) { return InstanceItemMethodItem( id: ManifestItemId.read(reader), + metadata: ManifestMetadata.read(reader), isStatic: reader.readBool(), functionType: ManifestFunctionType.read(reader), ); @@ -227,6 +259,9 @@ MethodElement2OrMember element, ) { var context = MatchContext(parent: instanceContext); + if (!metadata.match(context, element.metadata2)) { + return null; + } if (element.isStatic != isStatic) { return null; } @@ -252,6 +287,7 @@ InterfaceItem({ required super.id, + required super.metadata, required super.typeParameters, required super.members, required this.supertype, @@ -269,6 +305,11 @@ MatchContext? _matchInterfaceElement(InterfaceElementImpl2 element) { var context = MatchContext(parent: null); + + if (!metadata.match(context, element.metadata2)) { + return null; + } + context.addTypeParameters(element.typeParameters2); if (supertype.match(context, element.supertype) && interfaces.match(context, element.interfaces) && @@ -286,6 +327,7 @@ InterfaceItemConstructorItem({ required super.id, + required super.metadata, required super.isStatic, required this.isConst, required this.isFactory, @@ -300,6 +342,7 @@ // TODO(scheglov): initializers return InterfaceItemConstructorItem( id: id, + metadata: ManifestMetadata.encode(context, element.metadata2), isStatic: false, isConst: element.isConst, isFactory: element.isFactory, @@ -310,6 +353,7 @@ factory InterfaceItemConstructorItem.read(SummaryDataReader reader) { return InterfaceItemConstructorItem( id: ManifestItemId.read(reader), + metadata: ManifestMetadata.read(reader), isStatic: reader.readBool(), isConst: reader.readBool(), isFactory: reader.readBool(), @@ -322,6 +366,9 @@ ConstructorElementImpl2 element, ) { var context = MatchContext(parent: instanceContext); + if (!metadata.match(context, element.metadata2)) { + return null; + } if (isConst != element.isConst) { return null; } @@ -443,6 +490,7 @@ TopLevelFunctionItem({ required super.id, + required super.metadata, required this.functionType, }); @@ -453,6 +501,7 @@ }) { return TopLevelFunctionItem( id: id, + metadata: ManifestMetadata.encode(context, element.metadata2), functionType: element.type.encode(context), ); } @@ -460,6 +509,7 @@ factory TopLevelFunctionItem.read(SummaryDataReader reader) { return TopLevelFunctionItem( id: ManifestItemId.read(reader), + metadata: ManifestMetadata.read(reader), functionType: ManifestFunctionType.read(reader), ); } @@ -468,6 +518,11 @@ TopLevelFunctionElementImpl element, ) { var context = MatchContext(parent: null); + + if (!metadata.match(context, element.metadata2)) { + return null; + } + if (!functionType.match(context, element.type)) { return null; } @@ -484,13 +539,12 @@ } class TopLevelGetterItem extends TopLevelItem { - final ManifestMetadata metadata; final ManifestType returnType; final ManifestNode? constInitializer; TopLevelGetterItem({ required super.id, - required this.metadata, + required super.metadata, required this.returnType, required this.constInitializer, }); @@ -502,7 +556,10 @@ }) { return TopLevelGetterItem( id: id, - metadata: ManifestMetadata.encode(context, element.metadata2), + metadata: ManifestMetadata.encode( + context, + element.thisOrVariableMetadata, + ), returnType: element.returnType.encode(context), constInitializer: element.constInitializer?.encode(context), ); @@ -520,7 +577,7 @@ MatchContext? match(GetterElementImpl element) { var context = MatchContext(parent: null); - if (!metadata.match(context, element.metadata2)) { + if (!metadata.match(context, element.thisOrVariableMetadata)) { return null; } @@ -539,15 +596,15 @@ void write(BufferedSink sink) { sink.writeEnum(_ManifestItemKind.topLevelGetter); super.write(sink); - metadata.write(sink); returnType.write(sink); constInitializer.writeOptional(sink); } } -sealed class TopLevelItem extends ManifestItem { +sealed class TopLevelItem extends AnnotatedItem { TopLevelItem({ required super.id, + required super.metadata, }); factory TopLevelItem.read(SummaryDataReader reader) { @@ -568,12 +625,11 @@ } class TopLevelSetterItem extends TopLevelItem { - final ManifestMetadata metadata; final ManifestType valueType; TopLevelSetterItem({ required super.id, - required this.metadata, + required super.metadata, required this.valueType, }); @@ -584,7 +640,10 @@ }) { return TopLevelSetterItem( id: id, - metadata: ManifestMetadata.encode(context, element.metadata2), + metadata: ManifestMetadata.encode( + context, + element.thisOrVariableMetadata, + ), valueType: element.formalParameters[0].type.encode(context), ); } @@ -600,7 +659,7 @@ MatchContext? match(SetterElementImpl element) { var context = MatchContext(parent: null); - if (!metadata.match(context, element.metadata2)) { + if (!metadata.match(context, element.thisOrVariableMetadata)) { return null; } @@ -615,7 +674,6 @@ void write(BufferedSink sink) { sink.writeEnum(_ManifestItemKind.topLevelSetter); super.write(sink); - metadata.write(sink); valueType.write(sink); } } @@ -651,3 +709,13 @@ return null; } } + +extension _PropertyAccessExtension on PropertyAccessorElement2OrMember { + MetadataImpl get thisOrVariableMetadata { + if (isSynthetic) { + return variable3!.metadata2; + } else { + return metadata2; + } + } +}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart index 01ca5b4..42c93fc 100644 --- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart +++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -8236,6 +8236,44 @@ ); } + test_manifest_class_constructor_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +class A { + @Deprected('0') + A.foo(); + @Deprected('0') + A.bar(); +} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + bar: #M1 + foo: #M2 +''', + updatedCode: r''' +class A { + @Deprected('1') + A.foo(); + @Deprected('0') + A.bar(); +} +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + bar: #M1 + foo: #M3 +''', + ); + } + test_manifest_class_constructor_private() async { await _runLibraryManifestScenario( initialCode: r''' @@ -8474,6 +8512,44 @@ ); } + test_manifest_class_getter_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +class A { + @Deprecated('0') + int get foo => 0; + @Deprecated('0') + int get bar => 0; +} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + bar: #M1 + foo: #M2 +''', + updatedCode: r''' +class A { + @Deprecated('1') + int get foo => 0; + @Deprecated('0') + int get bar => 0; +} +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + bar: #M1 + foo: #M3 +''', + ); + } + test_manifest_class_getter_private_instance() async { await _runLibraryManifestScenario( initialCode: r''' @@ -8783,6 +8859,38 @@ ); } + test_manifest_class_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +@Deprecated('0') +class A {} +@Deprecated('0') +class B {} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + B: #M1 +''', + updatedCode: r''' +@Deprecated('0') +class A {} +@Deprecated('1') +class B {} +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + B: #M2 +''', + ); + } + test_manifest_class_method_add() async { await _runLibraryManifestScenario( initialCode: r''' @@ -9156,6 +9264,44 @@ ); } + test_manifest_class_method_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +class A { + @Deprecated('0') + void foo() {} + @Deprecated('0') + void bar() {} +} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + bar: #M1 + foo: #M2 +''', + updatedCode: r''' +class A { + @Deprecated('1') + void foo() {} + @Deprecated('0') + void bar() {} +} +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + A: #M0 + bar: #M1 + foo: #M3 +''', + ); + } + test_manifest_class_method_private_instance() async { await _runLibraryManifestScenario( initialCode: r''' @@ -10979,6 +11125,38 @@ ); } + test_manifest_topLevelFunction_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +@Deprected('0') +void a() {} +@Deprected('0') +void b() {} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + a: #M0 + b: #M1 +''', + updatedCode: r''' +@Deprected('0') +void a() {} +@Deprected('1') +void b() {} +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + a: #M0 + b: #M2 +''', + ); + } + test_manifest_topLevelFunction_private() async { await _runLibraryManifestScenario( initialCode: r''' @@ -11175,6 +11353,38 @@ ); } + test_manifest_topLevelGetter_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +@Deprecated('0') +int get a => 0; +@Deprecated('0') +int get b => 0; +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + a: #M0 + b: #M1 +''', + updatedCode: r''' +@Deprecated('0') +int get a => 0; +@Deprecated('1') +int get b => 0; +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + a: #M0 + b: #M2 +''', + ); + } + test_manifest_topLevelGetter_private() async { await _runLibraryManifestScenario( initialCode: r''' @@ -11273,6 +11483,38 @@ ); } + test_manifest_topLevelSetter_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +@Deprecated('0') +set a(int _) {} +@Deprecated('0') +set b(int _) {} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + a=: #M0 + b=: #M1 +''', + updatedCode: r''' +@Deprecated('0') +set a(int _) {} +@Deprecated('1') +set b(int _) {} +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + a=: #M0 + b=: #M2 +''', + ); + } + test_manifest_topLevelSetter_valueType() async { configuration.withElementManifests = true; await _runLibraryManifestScenario( @@ -11398,6 +11640,42 @@ ); } + test_manifest_topLevelVariable_metadata() async { + await _runLibraryManifestScenario( + initialCode: r''' +@Deprecated('0') +var a = 0; +@Deprecated('0') +var b = 0; +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + manifest + a: #M0 + a=: #M1 + b: #M2 + b=: #M3 +''', + updatedCode: r''' +@Deprecated('0') +var a = 0; +@Deprecated('1') +var b = 0; +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + manifest + a: #M0 + a=: #M1 + b: #M4 + b=: #M5 +''', + ); + } + test_manifest_topLevelVariable_private_const() async { await _runLibraryManifestScenario( initialCode: r'''
diff --git a/pkg/analyzer/test/src/dart/analysis/result_printer.dart b/pkg/analyzer/test/src/dart/analysis/result_printer.dart index 6e3118ae..edcd9bd 100644 --- a/pkg/analyzer/test/src/dart/analysis/result_printer.dart +++ b/pkg/analyzer/test/src/dart/analysis/result_printer.dart
@@ -753,6 +753,7 @@ void _writeClassItem(ClassItem item) { if (configuration.withElementManifests) { sink.withIndent(() { + _writeMetadata(item); _writeTypeParameters(item.typeParameters); _writeNamedType('supertype', item.supertype); }); @@ -779,10 +780,13 @@ sink.withIndent(() { switch (item) { case InstanceItemGetterItem(): + _writeMetadata(item); _writeNamedType('returnType', item.returnType); case InstanceItemMethodItem(): + _writeMetadata(item); _writeNamedType('functionType', item.functionType); case InterfaceItemConstructorItem(): + _writeMetadata(item); _writeNamedType('functionType', item.functionType); } }); @@ -799,6 +803,18 @@ sink.writeln('(${parts.join(', ')}) $idStr'); } + void _writeMetadata(AnnotatedItem item) { + if (configuration.withElementManifests) { + sink.writeElements( + 'metadata', + item.metadata.annotations.indexed.toList(), + (indexed) { + _writeNode('[${indexed.$1}]', indexed.$2.ast); + }, + ); + } + } + void _writeNamedId(LookupName name, ManifestItemId id) { var idStr = idProvider.manifestId(id); sink.writelnWithIndent('$name: $idStr'); @@ -840,6 +856,7 @@ void _writeTopLevelFunctionItem(TopLevelFunctionItem item) { if (configuration.withElementManifests) { sink.withIndent(() { + _writeMetadata(item); _writeNamedType('functionType', item.functionType); }); } @@ -848,6 +865,7 @@ void _writeTopLevelGetterItem(TopLevelGetterItem item) { if (configuration.withElementManifests) { sink.withIndent(() { + _writeMetadata(item); _writeNamedType('returnType', item.returnType); _writeNode('constInitializer', item.constInitializer); }); @@ -857,6 +875,7 @@ void _writeTopLevelSetterItem(TopLevelSetterItem item) { if (configuration.withElementManifests) { sink.withIndent(() { + _writeMetadata(item); _writeNamedType('valueType', item.valueType); }); }