diff --git a/pkg/vm/lib/embedder/visitor.dart b/pkg/vm/lib/embedder/visitor.dart index 44a28cf141d..de445e554dc 100644 --- a/pkg/vm/lib/embedder/visitor.dart +++ b/pkg/vm/lib/embedder/visitor.dart @@ -10,16 +10,23 @@ import 'package:vm/transformations/pragma.dart'; import 'collector.dart'; +bool _isDefault(ParsedEntryPointPragma pragma) => + pragma.type == PragmaEntryPointType.Default || + pragma.type == PragmaEntryPointType.DynamicallyCallable; + bool _allowsCall(ParsedEntryPointPragma pragma) => pragma.type == PragmaEntryPointType.Default || + pragma.type == PragmaEntryPointType.DynamicallyCallable || pragma.type == PragmaEntryPointType.CallOnly; bool _allowsGet(ParsedEntryPointPragma pragma) => pragma.type == PragmaEntryPointType.Default || + pragma.type == PragmaEntryPointType.DynamicallyCallable || pragma.type == PragmaEntryPointType.GetterOnly; bool _allowsSet(ParsedEntryPointPragma pragma) => pragma.type == PragmaEntryPointType.Default || + pragma.type == PragmaEntryPointType.DynamicallyCallable || pragma.type == PragmaEntryPointType.SetterOnly; EntryPointShimCollector visitLibrary( @@ -69,13 +76,14 @@ class EntryPointShimVisitor extends RecursiveVisitor { (p) => p.type != PragmaEntryPointType.Extendable && p.type != PragmaEntryPointType.ImplicitlyExtendable && - p.type != PragmaEntryPointType.CanBeOverridden, + p.type != PragmaEntryPointType.CanBeOverridden && + p.type != PragmaEntryPointType.CanBeUsedAsType, ); if (pragmas.isEmpty) return null; var pragma = pragmas.first; - if (pragma.type != PragmaEntryPointType.Default) { + if (!_isDefault(pragma)) { for (final p in pragmas.skip(1)) { - if (p.type == PragmaEntryPointType.Default) { + if (_isDefault(p)) { pragma = p; break; } diff --git a/pkg/vm/lib/transformations/dynamic_interface_annotator.dart b/pkg/vm/lib/transformations/dynamic_interface_annotator.dart index 20310b52db9..b038b1d70ad 100644 --- a/pkg/vm/lib/transformations/dynamic_interface_annotator.dart +++ b/pkg/vm/lib/transformations/dynamic_interface_annotator.dart @@ -16,6 +16,8 @@ import 'pragma.dart' kDynModuleCanBeUsedAsTypePragmaName, kDynModuleImplicitlyCallablePragmaName, kDynModuleImplicitlyExtendablePragmaName, + kDynModuleDynamicallyCallablePragmaName, + kDynModuleImplicitlyDynamicallyCallablePragmaName, kDynModuleCanBeOverriddenImplicitlyPragmaName; void annotateComponent( @@ -129,6 +131,29 @@ void annotateComponent( annotateInstanceMembers: false, logger: logger, ); + logger?.setActiveSection('dynamically-callable'); + final dynamicallyCallableAnnotator = annotateNodes( + spec.dynamicallyCallable, + kDynModuleDynamicallyCallablePragmaName, + baseUri, + coreTypes, + annotateClasses: false, + annotateFinalClasses: false, + annotateExtensionTypes: false, + annotateStaticMembers: false, + annotateInstanceMembers: true, + logger: logger, + ); + + final dynamicallyCallableImplicitUsesAnnotator = _ImplicitUsesAnnotator( + pragmaConstant( + coreTypes, + kDynModuleImplicitlyDynamicallyCallablePragmaName, + ), + dynamicallyCallableAnnotator.annotatedClasses, + dynamicallyCallableAnnotator.annotatedMembers, + ); + dynamicallyCallableImplicitUsesAnnotator.annotateDispatchTargets(component); } InstanceConstant pragmaConstant(CoreTypes coreTypes, String pragmaName) { diff --git a/pkg/vm/lib/transformations/pragma.dart b/pkg/vm/lib/transformations/pragma.dart index 98ffc4545ca..54f713d7bd8 100644 --- a/pkg/vm/lib/transformations/pragma.dart +++ b/pkg/vm/lib/transformations/pragma.dart @@ -36,6 +36,10 @@ const kDynModuleCallablePragmaName = "dyn-module:callable"; const kDynModuleImplicitlyCallablePragmaName = "dyn-module:implicitly-callable"; const kDynModuleCanBeUsedAsTypePragmaName = "dyn-module:can-be-used-as-type"; const kDynModuleEntryPointPragmaName = "dyn-module:entry-point"; +const kDynModuleDynamicallyCallablePragmaName = + "dyn-module:dynamically-callable"; +const kDynModuleImplicitlyDynamicallyCallablePragmaName = + "dyn-module:implicitly-dynamically-callable"; abstract class ParsedPragma {} @@ -48,6 +52,7 @@ enum PragmaEntryPointType { SetterOnly, CallOnly, CanBeUsedAsType, + DynamicallyCallable, } enum PragmaRecognizedType { AsmIntrinsic, GraphIntrinsic, Other } @@ -253,6 +258,11 @@ class ConstantPragmaAnnotationParser implements PragmaAnnotationParser { case kDynModuleCallablePragmaName: case kDynModuleImplicitlyCallablePragmaName: return getEntryPointTypeFromOptions(options, pragmaName); + case kDynModuleDynamicallyCallablePragmaName: + case kDynModuleImplicitlyDynamicallyCallablePragmaName: + return const ParsedEntryPointPragma( + PragmaEntryPointType.DynamicallyCallable, + ); case kDynModuleEntryPointPragmaName: return const ParsedDynModuleEntryPointPragma(); case kVmSharedPragmaName: diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart index d15667f0bca..5c9057d855c 100644 --- a/pkg/vm/lib/transformations/type_flow/analysis.dart +++ b/pkg/vm/lib/transformations/type_flow/analysis.dart @@ -626,7 +626,10 @@ final class _DispatchableInvocation extends _Invocation { if (selector.callKind != CallKind.PropertyGet) { if (selector is DynamicSelector) { - typeFlowAnalysis._methodsAndSettersCalledDynamically.add(target); + typeFlowAnalysis.recordMemberCalledDynamically( + target, + isGetter: false, + ); } else if (selector is VirtualSelector) { typeFlowAnalysis._calledViaThis.add(target); } else { @@ -634,7 +637,10 @@ final class _DispatchableInvocation extends _Invocation { } } else { if (selector is DynamicSelector) { - typeFlowAnalysis._gettersCalledDynamically.add(target); + typeFlowAnalysis.recordMemberCalledDynamically( + target, + isGetter: true, + ); } } @@ -907,11 +913,10 @@ final class _DispatchableInvocation extends _Invocation { // the mismatch in the number or names of arguments, // it still participates in the dynamic lookup. // So mark it as called dynamically so its signature is preserved. - if (selector.callKind != CallKind.PropertyGet) { - typeFlowAnalysis._methodsAndSettersCalledDynamically.add(target); - } else { - typeFlowAnalysis._gettersCalledDynamically.add(target); - } + typeFlowAnalysis.recordMemberCalledDynamically( + target, + isGetter: selector.callKind == CallKind.PropertyGet, + ); } _ReceiverTypeBuilder _getReceiverTypeBuilder( @@ -2333,6 +2338,15 @@ class TypeFlowAnalysis _tearOffTaken.add(target); } + @override + void recordMemberCalledDynamically(Member target, {required bool isGetter}) { + if (isGetter) { + _gettersCalledDynamically.add(target); + } else { + _methodsAndSettersCalledDynamically.add(target); + } + } + @override Procedure getClosureCallMethod(Closure closure) => _callMethodByClosure[closure] ??= _createCallMethod(closure); diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart index 423f1f5cb56..26908821380 100644 --- a/pkg/vm/lib/transformations/type_flow/native_code.dart +++ b/pkg/vm/lib/transformations/type_flow/native_code.dart @@ -41,6 +41,9 @@ abstract class EntryPointsListener { /// Record the fact that given member is torn off. void recordTearOff(Member target) {} + /// Record the fact that given member is called dynamically. + void recordMemberCalledDynamically(Member target, {required bool isGetter}); + /// Artificial call method corresponding to the given [closure]. Procedure getClosureCallMethod(Closure closure); @@ -202,6 +205,22 @@ class PragmaEntryPointsVisitor extends RecursiveVisitor { } } break; + case PragmaEntryPointType.DynamicallyCallable: + if (proc.isGetter) { + addSelector(CallKind.PropertyGet); + entryPoints.recordMemberCalledDynamically(proc, isGetter: true); + } else if (proc.isSetter) { + addSelector(CallKind.PropertySet); + entryPoints.recordMemberCalledDynamically(proc, isGetter: false); + } else { + addSelector(CallKind.Method); + entryPoints.recordMemberCalledDynamically(proc, isGetter: false); + if (!proc.isFactory) { + addSelector(CallKind.PropertyGet); + entryPoints.recordMemberCalledDynamically(proc, isGetter: true); + } + } + break; case PragmaEntryPointType.Extendable: case PragmaEntryPointType.ImplicitlyExtendable: throw "Error: only class can be extendable"; @@ -287,6 +306,14 @@ class PragmaEntryPointsVisitor extends RecursiveVisitor { addSelector(CallKind.PropertySet); } break; + case PragmaEntryPointType.DynamicallyCallable: + addSelector(CallKind.PropertyGet); + entryPoints.recordMemberCalledDynamically(field, isGetter: true); + if (field.hasSetter) { + addSelector(CallKind.PropertySet); + entryPoints.recordMemberCalledDynamically(field, isGetter: false); + } + break; case PragmaEntryPointType.CallOnly: throw "Error: 'call' is not a valid entry-point pragma annotation " "argument for the field $field.\n$_referenceToDocumentation"; diff --git a/pkg/vm/lib/transformations/type_flow/rta.dart b/pkg/vm/lib/transformations/type_flow/rta.dart index d74a91d5394..8b4161cb1d8 100644 --- a/pkg/vm/lib/transformations/type_flow/rta.dart +++ b/pkg/vm/lib/transformations/type_flow/rta.dart @@ -624,6 +624,9 @@ class _EntryPointsListenerImpl implements EntryPointsListener { @override void addDynamicallyExtendableClass(Class c) {} + @override + void recordMemberCalledDynamically(Member target, {required bool isGetter}) {} + @override Field getRecordPositionalField(RecordShape shape, int pos) => throw 'Unsupported operation'; diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart index 4d146a85d9e..26ee2e36cfa 100644 --- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart +++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart @@ -72,6 +72,9 @@ class FakeEntryPointsListener implements EntryPointsListener { @override void recordTearOff(Member target) {} + @override + void recordMemberCalledDynamically(Member target, {required bool isGetter}) {} + @override Procedure getClosureCallMethod(Closure closure) => closure.createCallMethod(); diff --git a/pkg/vm/testcases/transformations/dynamic_interface_annotator/detailed_dynamic_interface.json.expect b/pkg/vm/testcases/transformations/dynamic_interface_annotator/detailed_dynamic_interface.json.expect index 4781d0e1a36..f579e93e27d 100644 --- a/pkg/vm/testcases/transformations/dynamic_interface_annotator/detailed_dynamic_interface.json.expect +++ b/pkg/vm/testcases/transformations/dynamic_interface_annotator/detailed_dynamic_interface.json.expect @@ -1 +1 @@ -{"extendable":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"O"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"V"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"H"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"J"}],"can-be-overridden":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"D","member":"build"}],"callable":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"D","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"D","member":"build"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"K"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"K","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"K","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"N"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"N","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"O"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"O","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P1","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P1","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P2","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P2","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"R"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"R","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"S"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"S","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"T"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"T","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"V"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"V","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","member":"smethod10"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","member":"sfield9"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","member":"const11"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","member":"sfield9"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E5|addSuffix1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E5|get#addSuffix1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","extension_type":"E3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E3|get#info"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E3|constructor#"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E3|constructor#_#new#tearOff"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","extension_type":"E1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E1|get#info"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E1|constructor#_"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E1|constructor#_#_#tearOff"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E2|get#lastChar"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"D","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"D","member":"build"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","member":"smethod10"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","member":"sfield9"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"D","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"D","member":"build"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","member":"smethod10"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","member":"sfield9"}],"can-be-used-as-type":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","extension_type":"E1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"F"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"G"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","extension_type":"H"}]} +{"extendable":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"O"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"V"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"H"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"J"}],"can-be-overridden":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"D","member":"build"}],"callable":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"D","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"D","member":"build"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"K"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"K","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"K","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"N"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"N","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"O"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"O","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P1","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P1","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P2","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"P2","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"Q","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"R"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"R","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"S"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"S","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"T"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"T","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"U","member":"foo"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"V"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","class":"V","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","member":"smethod10"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","member":"sfield9"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.dart","member":"const11"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart","member":"sfield9"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E5|addSuffix1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E5|get#addSuffix1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","extension_type":"E3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E3|get#info"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E3|constructor#"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart","member":"E3|constructor#_#new#tearOff"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","extension_type":"E1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E1|get#info"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E1|constructor#_"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E1|constructor#_#_#tearOff"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","member":"E2|get#lastChar"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"D","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","class":"D","member":"build"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","member":"smethod10"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart","member":"sfield9"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"factory1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"factory2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"imethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"smethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"ifield1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"A","member":"sfield3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"imethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"imethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"smethod7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"B","member":"ifield5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"D"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"D","member":""},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","class":"D","member":"build"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","member":"smethod10"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart","member":"sfield9"}],"can-be-used-as-type":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib5.dart","extension_type":"E1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"F"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","class":"G"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart","extension_type":"H"}],"dynamically-callable":[{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"A","member":"dcMethod1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"A","member":"dcMethod2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"A","member":"dcGetter1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"A","member":"dcSetter1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"B","member":"dcMethod3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"B","member":"dcMethod4"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"B","member":"dcGetter2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"B","member":"dcSetter2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"B","member":"dcField1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"B","member":"dcField2"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"D","member":"method1"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"E","member":"dcMethod5"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"E","member":"dcGetter3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"E","member":"dcSetter3"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"E","member":"dcField7"},{"library":"file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart","class":"E","member":"dcField8"}]} diff --git a/pkg/vm/testcases/transformations/dynamic_interface_annotator/dynamic_interface.yaml b/pkg/vm/testcases/transformations/dynamic_interface_annotator/dynamic_interface.yaml index 956483b7f58..0dc49a3cd51 100644 --- a/pkg/vm/testcases/transformations/dynamic_interface_annotator/dynamic_interface.yaml +++ b/pkg/vm/testcases/transformations/dynamic_interface_annotator/dynamic_interface.yaml @@ -33,3 +33,22 @@ can-be-overridden: class: 'D' member: 'build' - library: 'lib4.dart' + +dynamically-callable: + - library: 'lib6.dart' + class: ['A', 'B', 'D'] + - library: 'lib6.dart' + class: E + member: dcMethod5 + - library: 'lib6.dart' + class: E + member: 'get:dcGetter3' + - library: 'lib6.dart' + class: E + member: 'set:dcSetter3' + - library: 'lib6.dart' + class: E + member: dcField7 + - library: 'lib6.dart' + class: E + member: dcField8 diff --git a/pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart b/pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart new file mode 100644 index 00000000000..f0f48a19ac3 --- /dev/null +++ b/pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart @@ -0,0 +1,62 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class A { + void dcMethod1() {} + void dcMethod2(String x, int y) {} + int get dcGetter1 => 1; + void set dcSetter1(int value) {} + static void staticMethod1() {} + + A(); + factory A.factory() => A(); +} + +class A2 extends A { + @override + void dcMethod1() { + print('1'); + } +} + +class A3 implements A { + @override + void dcMethod1() { + print('1'); + } + + @override + void dcMethod2(String x, int y) {} + @override + int get dcGetter1 => 1; + @override + void set dcSetter1(int value) {} +} + +class B { + final int dcField1 = 1; + int dcField2 = 1; + + void dcMethod3() {} + void dcMethod4(String x, int y) {} + int get dcGetter2 => 1; + void set dcSetter2(int value) {} +} + +class C { + int _dcPrivateMethod1() => 1; +} + +mixin D on C { + int method1() => (this as dynamic)._dcPrivateMethod1(); +} + +class E { + void dcMethod5() {} + int get dcGetter3 => 1; + void set dcSetter3(int value) {} + final int dcField7 = 1; + int dcField8 = 1; + int dcField9 = 1; // unexposed +} diff --git a/pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart.expect b/pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart.expect new file mode 100644 index 00000000000..ae60908cda6 --- /dev/null +++ b/pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart.expect @@ -0,0 +1,106 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + constructor •() → self::A + : super core::Object::•() + ; + @#C3 + method dcMethod1() → void {} + @#C3 + method dcMethod2(core::String x, core::int y) → void {} + @#C3 + get dcGetter1() → core::int + return 1; + @#C3 + set dcSetter1(core::int value) → void {} + static method staticMethod1() → void {} + static factory factory() → self::A + return new self::A::•(); +} +class A2 extends self::A { + synthetic constructor •() → self::A2 + : super self::A::•() + ; + @#C4 + @#C6 + method dcMethod1() → void { + core::print("1"); + } +} +class A3 extends core::Object implements self::A { + synthetic constructor •() → self::A3 + : super core::Object::•() + ; + @#C4 + @#C6 + method dcMethod1() → void { + core::print("1"); + } + @#C4 + @#C6 + method dcMethod2(core::String x, core::int y) → void {} + @#C4 + @#C6 + get dcGetter1() → core::int + return 1; + @#C4 + @#C6 + set dcSetter1(core::int value) → void {} +} +class B extends core::Object { + @#C3 + final field core::int dcField1 = 1; + @#C3 + field core::int dcField2 = 1; + synthetic constructor •() → self::B + : super core::Object::•() + ; + @#C3 + method dcMethod3() → void {} + @#C3 + method dcMethod4(core::String x, core::int y) → void {} + @#C3 + get dcGetter2() → core::int + return 1; + @#C3 + set dcSetter2(core::int value) → void {} +} +class C extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; + method _dcPrivateMethod1() → core::int + return 1; +} +abstract class D extends self::C /*isMixinDeclaration*/ { + @#C3 + method method1() → core::int + return (this as dynamic){dynamic}._dcPrivateMethod1() as{TypeError,ForDynamic} core::int; +} +class E extends core::Object { + @#C3 + final field core::int dcField7 = 1; + @#C3 + field core::int dcField8 = 1; + field core::int dcField9 = 1; + synthetic constructor •() → self::E + : super core::Object::•() + ; + @#C3 + method dcMethod5() → void {} + @#C3 + get dcGetter3() → core::int + return 1; + @#C3 + set dcSetter3(core::int value) → void {} +} +constants { + #C1 = "dyn-module:dynamically-callable" + #C2 = null + #C3 = core::pragma {name:#C1, options:#C2} + #C4 = core::_Override {} + #C5 = "dyn-module:implicitly-dynamically-callable" + #C6 = core::pragma {name:#C5, options:#C2} +} diff --git a/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart b/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart index a3b8a2fe515..d3a90a34617 100644 --- a/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart +++ b/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart @@ -6,6 +6,7 @@ import 'lib1.dart'; import 'lib2.dart'; import 'lib3.dart'; import 'lib4.dart'; +import 'lib6.dart'; import 'prefix/lib1.dart'; import 'prefix/lib2.dart'; diff --git a/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart.expect b/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart.expect index 0795e1003c3..b8239c25281 100644 --- a/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart.expect +++ b/pkg/vm/testcases/transformations/dynamic_interface_annotator/main.dart.expect @@ -5,6 +5,7 @@ import "file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib1.d import "file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib2.dart"; import "file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib3.dart"; import "file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib4.dart"; +import "file:pkg/vm/testcases/transformations/dynamic_interface_annotator/lib6.dart"; import "file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib1.dart"; import "file:pkg/vm/testcases/transformations/dynamic_interface_annotator/prefix/lib2.dart"; diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_module_dynamically_callable.dart b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_module_dynamically_callable.dart new file mode 100644 index 00000000000..3954e460e12 --- /dev/null +++ b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_module_dynamically_callable.dart @@ -0,0 +1,78 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test for @pragma('dyn-module:dynamically-callable'). + +abstract class A { + @pragma('dyn-module:dynamically-callable') + Object method1(); // Not eliminated + + @pragma('dyn-module:dynamically-callable') + Object method2() => 42; // Not eliminated + + Object method3() => 1; // Eliminated +} + +class B extends A { + @pragma('dyn-module:implicitly-dynamically-callable') + int method1() => 42; // Not eliminated + + Object method4() => 1; // Eliminated +} + +class C implements A { + @pragma('dyn-module:implicitly-dynamically-callable') + int method1() => 42; // Not eliminated + + @pragma('dyn-module:implicitly-dynamically-callable') + int method2() => 42; // Not eliminated + + Object method3() => 2; // Eliminated + + @pragma('dyn-module:dynamically-callable') + Object method5() => 42; // Not eliminated + + Object method6() => 1; // Eliminated +} + +abstract class D { + Object method7(); // Eliminated +} + +class E implements D { + @pragma('dyn-module:dynamically-callable') + int get field1 => 0; + + int method7() => 3; // Eliminated +} + +abstract class F { + Object method8(); // Eliminated +} + +class G implements F { + @pragma('dyn-module:implicitly-dynamically-callable') + int field1 = 0; // Not eliminated + + int field2 = 0; // Eliminated + + int method8() => 4; // Eliminated + + @pragma('dyn-module:dynamically-callable') + int method9() => 42; // Eliminated + + @pragma('dyn-module:dynamically-callable') + int get getter2 => 0; // Not eliminated + + @pragma('dyn-module:dynamically-callable') + void set setter2(int v) {} // Not eliminated + + int field3 = 0; // Eliminated + + int get getter4 => 0; // Eliminated + + void set setter4(int v) {} // Eliminated +} + +main() {} diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_module_dynamically_callable.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_module_dynamically_callable.dart.expect new file mode 100644 index 00000000000..dbd3ee96f0a --- /dev/null +++ b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_module_dynamically_callable.dart.expect @@ -0,0 +1,69 @@ +library #lib; +import self as self; +import "dart:core" as core; + +abstract class A extends core::Object { + + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] + @#C3 + abstract method method1() → core::Object; + + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] + @#C3 + abstract method method2() → core::Object; +} +abstract class B extends core::Object { + + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] + @#C5 + abstract method method1() → core::int; +} +abstract class C extends core::Object { + + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] + @#C5 + abstract method method1() → core::int; + + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] + @#C5 + abstract method method2() → core::int; + + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] + @#C3 + abstract method method5() → core::Object; +} +abstract class E extends core::Object { + + [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13] + @#C3 + abstract get field1() → core::int; +} +abstract class G extends core::Object { + + [@vm.unreachable.metadata=] + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:14,getterSelectorId:15] + @#C5 + field core::int field1; + + [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:16,getterSelectorId:17] + @#C3 + abstract method method9() → core::int; + + [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:18] + @#C3 + abstract get getter2() → core::int; + + [@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19] + @#C3 + abstract set setter2(core::int v) → void; +} + +[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)] +static method main() → dynamic {} +constants { + #C1 = "dyn-module:dynamically-callable" + #C2 = null + #C3 = core::pragma {name:#C1, options:#C2} + #C4 = "dyn-module:implicitly-dynamically-callable" + #C5 = core::pragma {name:#C4, options:#C2} +}