From 2540a8fae52e63daf9da68c7c142d26eb4c032fd Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Tue, 14 Apr 2026 17:16:33 -0700 Subject: [PATCH] [cfe,dyn_modules] add `dynamically-callable` section to dynamic interface This introduces the `dynamically-callable` section in the dynamic interface and adds an initial, but incomplete, validation pass for it. The current validator: * Checks that dynamic calls use a selector that matches one of the exposed members in the `dynamically-callable` section. * Validates that subtypes of `dynamically-callable` classes added in a dynamic module don't overlap with classes implementing `noSuchMethod`. Note that the latter check is incomplete. Additional checks need to be added when building the host app to reject subtypes defined in the host. Future changes: * validate during host compilation about other subtypes * move validation for classes exposed in the dynamic interface to be done while compiling the host * reject mixin methods that contain dynamic calls during host compilation. * accept providing an allow list of valid selectors during compilation of dynamic modules, so it module-to-module calls are supported too. TEST=CFE unit tests Change-Id: I8d12192ef374c34a48fbdf2ba5002d2850ce926f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494001 Reviewed-by: Alexander Markov Commit-Queue: Sigmund Cherem --- pkg/front_end/lib/src/codes/diagnostic.g.dart | 132 +++++- .../src/kernel/dynamic_module_validator.dart | 237 +++++++++- pkg/front_end/messages.status | 6 + pkg/front_end/messages.yaml | 39 +- .../test/spell_checking_list_code.txt | 3 + .../test/spell_checking_list_common.txt | 5 + .../test/spell_checking_list_messages.txt | 1 + pkg/front_end/test/testing/suite.dart | 2 + .../dynamic_modules/dynamic_interface.yaml | 43 ++ .../general/dynamic_modules/main.dart | 37 +- .../dynamic_modules/main.dart.strong.expect | 434 ++++++++++++------ .../main.dart.strong.modular.expect | 281 +++++++----- .../main.dart.strong.outline.expect | 152 +++++- .../main.dart.strong.transformed.expect | 434 ++++++++++++------ .../main.dart.textual_outline.expect | 11 + .../main.dart.textual_outline_modelled.expect | 10 + .../general/dynamic_modules/main_lib1.dart | 53 +++ .../general/dynamic_modules/main_lib5.dart | 10 + .../general/dynamic_modules/test.options | 1 + pkg/vm/dynamic_interface.md | 10 + 20 files changed, 1485 insertions(+), 416 deletions(-) create mode 100644 pkg/front_end/testcases/general/dynamic_modules/main_lib5.dart diff --git a/pkg/front_end/lib/src/codes/diagnostic.g.dart b/pkg/front_end/lib/src/codes/diagnostic.g.dart index 6bf66b7bfa2..1af02ce21fc 100644 --- a/pkg/front_end/lib/src/codes/diagnostic.g.dart +++ b/pkg/front_end/lib/src/codes/diagnostic.g.dart @@ -832,6 +832,25 @@ Message _withArgumentsClassShouldBeListedAsExtendableInDynamicInterface({ ); } +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template +classWithNoSuchMethodSubtypeCause = const Template( + "ClassWithNoSuchMethodSubtypeCause", + withArguments: _withArgumentsClassWithNoSuchMethodSubtypeCause, +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsClassWithNoSuchMethodSubtypeCause({ + required String name, +}) { + var name_0 = conversions.validateString(name); + return new Message( + classWithNoSuchMethodSubtypeCause, + problemMessage: """Subtype '${name_0}' implements 'noSuchMethod' here.""", + arguments: {'name': name}, + ); +} + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template< Message Function({required String className, required String memberName}) @@ -2684,11 +2703,118 @@ Message _withArgumentsDuplicatedRecordTypeFieldNameContext({ } // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. -const MessageCode dynamicCallsAreNotAllowedInDynamicModule = const MessageCode( - "DynamicCallsAreNotAllowedInDynamicModule", - problemMessage: """Dynamic calls are not allowed in a dynamic module.""", +const MessageCode dynamicCallsAreDisallowedByDefault = const MessageCode( + "DynamicCallsAreDisallowedByDefault", + problemMessage: + """Dynamic calls are not allowed in dynamic modules by default as they increase risks of runtime errors in applications.""", + correctionMessage: + """You can bypass this error by using '--allow-dynamic-calls-in-dynamic-modules'.""", ); +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode +dynamicCallsAreDiscouragedInDynamicModules = const MessageCode( + "DynamicCallsAreDiscouragedInDynamicModules", + severity: CfeSeverity.warning, + problemMessage: + """Dynamic calls are discouraged in dynamic modules as they may fail at runtime if their target is not properly exposed as 'dynamically-callable'.""", + correctionMessage: + """Consider avoiding dynamic calls. You can remove '--allow-dynamic-calls-in-dynamic-modules' to see where dynamic calls are used.""", +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template +dynamicCallsAreNotAllowedInDynamicModule = const Template( + "DynamicCallsAreNotAllowedInDynamicModule", + withArguments: _withArgumentsDynamicCallsAreNotAllowedInDynamicModule, +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsDynamicCallsAreNotAllowedInDynamicModule({ + required String name, +}) { + var name_0 = conversions.validateString(name); + return new Message( + dynamicCallsAreNotAllowedInDynamicModule, + problemMessage: + """Dynamic call to selector '${name_0}' is not allowed in a dynamic module.""", + correctionMessage: + """Try listing '${name_0}' as 'dynamically-callable' in the dynamic interface specification.""", + arguments: {'name': name}, + ); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template +dynamicallyCallableWithNoSuchMethod = const Template( + "DynamicallyCallableWithNoSuchMethod", + withArguments: _withArgumentsDynamicallyCallableWithNoSuchMethod, +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsDynamicallyCallableWithNoSuchMethod({ + required String name, +}) { + var name_0 = conversions.validateString(name); + return new Message( + dynamicallyCallableWithNoSuchMethod, + problemMessage: + """Cannot expose class '${name_0}' because it declares or inherits a 'noSuchMethod' declaration.""", + correctionMessage: + """Try removing the 'noSuchMethod' declaration or not exposing the class.""", + arguments: {'name': name}, + ); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template< + Message Function({required String name, required String subtype}) +> +dynamicallyCallableWithNoSuchMethodDynamicSubtype = const Template( + "DynamicallyCallableWithNoSuchMethodDynamicSubtype", + withArguments: + _withArgumentsDynamicallyCallableWithNoSuchMethodDynamicSubtype, +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsDynamicallyCallableWithNoSuchMethodDynamicSubtype({ + required String name, + required String subtype, +}) { + var subtype_0 = conversions.validateString(subtype); + var name_0 = conversions.validateString(name); + return new Message( + dynamicallyCallableWithNoSuchMethodDynamicSubtype, + problemMessage: + """Cannot define 'noSuchMethod' on '${subtype_0}' because it is a subtype of '${name_0}', which was exposed as dynamically-callable.""", + correctionMessage: + """Try removing the 'noSuchMethod' declaration or no longer expose '${name_0}' as dynamically-callable.""", + arguments: {'name': name, 'subtype': subtype}, + ); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template +dynamicallyCallableWithNoSuchMethodHostSubtype = const Template( + "DynamicallyCallableWithNoSuchMethodHostSubtype", + withArguments: _withArgumentsDynamicallyCallableWithNoSuchMethodHostSubtype, +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsDynamicallyCallableWithNoSuchMethodHostSubtype({ + required String name, +}) { + var name_0 = conversions.validateString(name); + return new Message( + dynamicallyCallableWithNoSuchMethodHostSubtype, + problemMessage: + """Cannot expose class '${name_0}' because it has a subtype with a 'noSuchMethod' declaration.""", + correctionMessage: + """Try removing the 'noSuchMethod' declaration from the subtype or not exposing the class.""", + arguments: {'name': name}, + ); +} + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const MessageCode emptyMapPattern = const MessageCode( "EmptyMapPattern", diff --git a/pkg/front_end/lib/src/kernel/dynamic_module_validator.dart b/pkg/front_end/lib/src/kernel/dynamic_module_validator.dart index 9f2d6cbad72..0b76fbd5e9e 100644 --- a/pkg/front_end/lib/src/kernel/dynamic_module_validator.dart +++ b/pkg/front_end/lib/src/kernel/dynamic_module_validator.dart @@ -7,6 +7,7 @@ import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; import 'package:kernel/core_types.dart' show CoreTypes; import 'package:kernel/library_index.dart' show LibraryIndex; +import 'package:kernel/names.dart' show noSuchMethodName; import 'package:yaml/yaml.dart'; import '../source/source_loader.dart' show SourceLoader; import '../api_prototype/lowering_predicates.dart' @@ -72,6 +73,7 @@ class DynamicInterfaceYamlFile { 'can-be-overridden', 'callable', 'can-be-used-as-type', + 'dynamically-callable', }); } } @@ -84,6 +86,7 @@ class DynamicInterfaceYamlFile { YamlList? get canBeOverridden => sections['can-be-overridden']; YamlList? get callable => sections['callable']; YamlList? get canBeUsedAsType => sections['can-be-used-as-type']; + YamlList? get dynamicallyCallable => sections['dynamically-callable']; // Coverage-ignore(suite): Not run. Set get libraries => { @@ -109,6 +112,7 @@ class DynamicInterfaceSpecification { final Set canBeOverridden = {}; final Set callable = {}; final Set canBeUsedAsType = {}; + final Set dynamicallyCallable = {}; factory DynamicInterfaceSpecification( String dynamicInterfaceSpecification, @@ -170,6 +174,16 @@ class DynamicInterfaceSpecification { allowStaticDeclarations: false, allowInstanceMembers: false, ); + + _parseList( + yamlFile.dynamicallyCallable, + dynamicallyCallable, + baseUri, + component, + libraryIndex, + allowStaticDeclarations: false, + allowInstanceMembers: true, + ); } void _parseList( @@ -450,6 +464,7 @@ class _DynamicModuleValidator extends RecursiveVisitor { final SourceLoader loader; final bool allowDynamicCallsInDynamicModules; final Set _visitedConstants = new Set.identity(); + late final _DynamicCallValidator _dynamicCallValidator; TreeNode? _enclosingTreeNode; @@ -465,6 +480,8 @@ class _DynamicModuleValidator extends RecursiveVisitor { _expandNodes(spec.extendable); _expandNodes(spec.canBeOverridden); _expandNodes(spec.canBeUsedAsType); + _expandNodes(spec.dynamicallyCallable); + _dynamicCallValidator = new _DynamicCallValidator(this)..run(); } // Add nodes which do not have direct relation to its logical "parent" node. @@ -562,6 +579,8 @@ class _DynamicModuleValidator extends RecursiveVisitor { ); _verifyOverrides(setterImplementationMembers, setterInterfaceMembers); } + + _verifyDynamicallyCallableClass(node); super.visitClass(node); } @@ -645,7 +664,6 @@ class _DynamicModuleValidator extends RecursiveVisitor { } @override - // Coverage-ignore(suite): Not run. void visitSuperMethodInvocation(SuperMethodInvocation node) { _verifyCallable(node.interfaceTarget, node); super.visitSuperMethodInvocation(node); @@ -707,26 +725,26 @@ class _DynamicModuleValidator extends RecursiveVisitor { @override void visitDynamicGet(DynamicGet node) { - _dynamicCall(node); + _verifyDynamicallyCallable(new _Selector(.PropertyGet, node.name), node); super.visitDynamicGet(node); } @override void visitDynamicSet(DynamicSet node) { - _dynamicCall(node); + _verifyDynamicallyCallable(new _Selector(.PropertySet, node.name), node); super.visitDynamicSet(node); } @override void visitDynamicInvocation(DynamicInvocation node) { - _dynamicCall(node); + _verifyDynamicallyCallable(new _Selector(.Method, node.name), node); super.visitDynamicInvocation(node); } @override void visitRelationalPattern(RelationalPattern node) { if (node.accessKind == RelationalAccessKind.Dynamic) { - _dynamicCall(node); + _verifyDynamicallyCallable(new _Selector(.Method, node.name!), node); } super.visitRelationalPattern(node); } @@ -734,7 +752,10 @@ class _DynamicModuleValidator extends RecursiveVisitor { @override void visitNamedPattern(NamedPattern node) { if (node.accessKind == ObjectAccessKind.Dynamic) { - _dynamicCall(node); + _verifyDynamicallyCallable( + new _Selector(.PropertyGet, node.fieldName), + node, + ); } super.visitNamedPattern(node); } @@ -813,13 +834,38 @@ class _DynamicModuleValidator extends RecursiveVisitor { void visitTypedefTearOffConstantReference(TypedefTearOffConstant node) => throw 'Unexpected node ${node.runtimeType} $node'; - void _dynamicCall(TreeNode node) { - loader.addProblem( - diag.dynamicCallsAreNotAllowedInDynamicModule, - node.fileOffset, - noLength, - node.location!.file, - ); + bool _warningEmitted = false; + void _verifyDynamicallyCallable(_Selector selector, TreeNode node) { + if (allowDynamicCallsInDynamicModules) { + if (!_warningEmitted) { + _warningEmitted = true; + loader.addProblem( + diag.dynamicCallsAreDiscouragedInDynamicModules, + TreeNode.noOffset, + noLength, + node.location!.file, + ); + } + + if (!_dynamicCallValidator.isAllowed(selector)) { + loader.addProblem( + diag.dynamicCallsAreNotAllowedInDynamicModule.withArguments( + name: selector.diagnosticName, + ), + node.fileOffset, + noLength, + node.location!.file, + ); + } + } else { + // Coverage-ignore-block(suite): Not run. + loader.addProblem( + diag.dynamicCallsAreDisallowedByDefault, + node.fileOffset, + noLength, + node.location!.file, + ); + } } void _verifyCanBeUsedAsType(TreeNode target, TreeNode node) { @@ -924,6 +970,23 @@ class _DynamicModuleValidator extends RecursiveVisitor { } } + // Verify that any subtype of dynamically-callable classes don't define or + // inherit a `noSuchMethod` override: + void _verifyDynamicallyCallableClass(Class node) { + if (!_dynamicCallValidator._hasUserNoSuchMethod(node)) return; + Class? result = _dynamicCallValidator.getDynamicallyCallableSupertype(node); + if (result == null) return; + loader.addProblem( + diag.dynamicallyCallableWithNoSuchMethodDynamicSubtype.withArguments( + name: result.name, + subtype: node.name, + ), + node.fileOffset, + noLength, + node.location!.file, + ); + } + // Unwrap synthetic stubs to get actual member. Member _unwrapStubs(Member member) { if (member is Procedure) { @@ -1025,7 +1088,151 @@ class _DynamicModuleValidator extends RecursiveVisitor { ExtensionTypeDeclaration() => node.name[0] != '_' && _isSpecified(node.enclosingLibrary, specified), Library() => false, - // Coverage-ignore(suite): Not run. - _ => throw 'Unexpected node ${node.runtimeType} $node', + _ => // Coverage-ignore(suite): Not run. + throw 'Unexpected node ${node.runtimeType} $node', }; } + +/// Performs preparation work required before +/// [_DynamicModulesValidator] visits the dynamic module. +/// +/// Currently this includes: +/// * Ensuring names of members exposed dynamically are registered. The +/// registered names will be used while validating dynamic call nodes later. +/// * Check for invalid exposed nodes because of classes implementing +/// `noSuchMethod`. Both classes in the dynamic interface and their subtypes +/// in the host app. +class _DynamicCallValidator { + final _DynamicModuleValidator validator; + final Set<_Selector> _dynamicallyCallable = {}; + final Set classesExposedDynamically = {}; + DynamicInterfaceSpecification get spec => validator.spec; + + _DynamicCallValidator(this.validator); + + /// Whether [selectorName] should be allowed in a dynamic module. + bool isAllowed(_Selector selector) => _dynamicallyCallable.contains(selector); + + /// Registers exposed selectors based on [spec] and validates classes in + /// [component] to ensure dynamically callable classes cannot directly or + /// indirectly override `noSuchMethod`. + void run() { + if (spec.dynamicallyCallable.isEmpty) return; + + for (TreeNode node in spec.dynamicallyCallable) { + if (node is Member) { + checkExposedClass(node.enclosingClass!, node); + registerSelectorName(node); + } else if (node is Class) { + checkExposedClass(node, node); + registerClassMembers(node); + } else { + for (Class c in (node as Library).classes) { + checkExposedClass(c, c); + registerClassMembers(c); + } + } + } + } + + /// Registers the implicit selector name of [node] in the the allow-list of + /// dynamically callable selectors. + void registerSelectorName(Member node) { + if (!node.isInstanceMember) return; + switch (node) { + case Field(): + _dynamicallyCallable.add(new _Selector(.PropertyGet, node.name)); + if (node.hasSetter) { + _dynamicallyCallable.add(new _Selector(.PropertySet, node.name)); + } + case Procedure() when node.isGetter: + _dynamicallyCallable.add(new _Selector(.PropertyGet, node.name)); + case Procedure() when node.isSetter: + _dynamicallyCallable.add(new _Selector(.PropertySet, node.name)); + case _: + _dynamicallyCallable.add(new _Selector(.Method, node.name)); + _dynamicallyCallable.add(new _Selector(.PropertyGet, node.name)); + } + } + + /// Registers the implicit selectors from all members defined in [cls]. + void registerClassMembers(Class cls) { + for (Procedure p in cls.procedures) { + registerSelectorName(p); + } + for (Field f in cls.fields) { + registerSelectorName(f); + } + } + + /// Checks that [cls] doesn't contain a `noSuchMethod` override. + /// + // TODO(sigmund): perform this check only when compiling the host app. + // TODO(sigmund): check subtypes of dynamically-callable classes defined in + // the host. + void checkExposedClass(Class cls, TreeNode node) { + if (!classesExposedDynamically.add(cls)) return; + bool result = _hasUserNoSuchMethod(cls); + if (result) { + validator.loader.addProblem( + diag.dynamicallyCallableWithNoSuchMethod.withArguments(name: cls.name), + // TODO(sigmund): consider reporting an offset in the + // dynamic_interface.yaml file instead. + node.fileOffset, + noLength, + node.location!.file, + ); + } + } + + /// Searches whether a supertype of [cls] is exposed as + /// `dynamically-callable`. If so, return the first such supertype, otherwise + /// return `null`. + Class? getDynamicallyCallableSupertype(Class? cls) { + if (cls == null) return null; + if (classesExposedDynamically.contains(cls)) return cls; + Class? result = getDynamicallyCallableSupertype(cls.superclass); + if (result != null) return result; + for (Supertype type in cls.implementedTypes) { + Class? found = getDynamicallyCallableSupertype(type.classNode); + if (found != null) return found; + } + return null; + } + + /// Whether [cls] defines or inherits a user `noSuchMethod` definition. + bool _hasUserNoSuchMethod(Class cls) { + // Note: we don't use `hierarchy.getInterfaceMember(cls, noSuchMethodName)` + // because [hierarchy] only indexes code reachable from the dynamic + // module and excludes the rest of the host libraries. + if (cls == validator.hierarchy.coreTypes.objectClass) return false; + if (cls.procedures.any((p) => p.name == noSuchMethodName)) { + return true; + } + return _hasUserNoSuchMethod(cls.superclass!); + } +} + +enum _SelectorKind { Method, PropertyGet, PropertySet } + +class _Selector { + final _SelectorKind kind; + final Name name; + + _Selector(this.kind, this.name); + + String get _prefix => switch (kind) { + .Method => '', + .PropertyGet => 'get:', + .PropertySet => 'set:', + }; + + String get diagnosticName => '$_prefix${name.text}'; + + @override + bool operator ==(other) => + other is _Selector && kind == other.kind && name == other.name; + + @override + int get hashCode => Object.hash(kind, name); +} diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index e6c6135eeac..1257843efa9 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -13,6 +13,7 @@ front_end/CantInferPackagesFromPackageUri/example: missingExample # We don't con front_end/ClassShouldBeListedAsCallableInDynamicInterface/example: missingExample # Can't do dynamic modules stuff in messages suite. front_end/ClassShouldBeListedAsCanBeUsedAsTypeInDynamicInterface/example: missingExample # Can't do dynamic modules stuff in messages suite. front_end/ClassShouldBeListedAsExtendableInDynamicInterface/example: missingExample # Can't do dynamic modules stuff in messages suite. +front_end/ClassWithNoSuchMethodSubtypeCause/example: missingExample # Can't do dynamic modules stuff in messages suite. front_end/ConstEvalError/example: missingExample # Uncovered, at least outside of constant stress testing. front_end/ConstEvalGetterNotFound/example: missingExample # Not covered. front_end/ConstEvalInvalidPropertyGet/example: missingExample # Uncovered, at least outside of constant stress testing. @@ -30,7 +31,12 @@ front_end/DillOutlineSummary/example: missingExample # Used for verbose output. front_end/DuplicatedDeclarationUse/part_wrapped_script1: hasOnlyUnrelatedMessages # Seemingly this is not issued as an error, but ends up in the kernel AST. front_end/DuplicatedDeclarationUse/script1: hasOnlyUnrelatedMessages # Seemingly this is not issued as an error, but ends up in the kernel AST. front_end/DuplicatedDeclarationUse/script2: hasOnlyUnrelatedMessages # Seemingly this is not issued as an error, but ends up in the kernel AST. +front_end/DynamicCallsAreDisallowedByDefault/example: missingExample # Can't do dynamic modules stuff in messages suite. +front_end/DynamicCallsAreDiscouragedInDynamicModules/example: missingExample # Can't do dynamic modules stuff in messages suite. front_end/DynamicCallsAreNotAllowedInDynamicModule/example: missingExample # Can't do dynamic modules stuff in messages suite. +front_end/DynamicallyCallableWithNoSuchMethod/example: missingExample # Can't do dynamic modules stuff in messages suite. +front_end/DynamicallyCallableWithNoSuchMethodDynamicSubtype/example: missingExample # Can't do dynamic modules stuff in messages suite. +front_end/DynamicallyCallableWithNoSuchMethodHostSubtype/example: missingExample # Can't do dynamic modules stuff in messages suite. front_end/ExceptionReadingFile/example: missingExample # Requires an exception (generally not a FileSystemException) to occur when reading a file. front_end/ExpectedBlockToSkip/example: missingExample # Seemingly only used when skipping a block in a special parser. front_end/ExpectedButGot2/example: missingExample # Only used in experimental code. diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 7bcb80cbb88..a998c28c8e5 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -677,8 +677,45 @@ missingExplicitConst: } dynamicCallsAreNotAllowedInDynamicModule: + parameters: + String name: The selector name. + problemMessage: "Dynamic call to selector '#name' is not allowed in a dynamic module." + correctionMessage: "Try listing '#name' as 'dynamically-callable' in the dynamic interface specification." + +dynamicCallsAreDiscouragedInDynamicModules: parameters: none - problemMessage: "Dynamic calls are not allowed in a dynamic module." + problemMessage: "Dynamic calls are discouraged in dynamic modules as they may fail at runtime if their target is not properly exposed as 'dynamically-callable'." + correctionMessage: "Consider avoiding dynamic calls. You can remove '--allow-dynamic-calls-in-dynamic-modules' to see where dynamic calls are used." + severity: WARNING + +dynamicCallsAreDisallowedByDefault: + parameters: none + problemMessage: "Dynamic calls are not allowed in dynamic modules by default as they increase risks of runtime errors in applications." + correctionMessage: "You can bypass this error by using '--allow-dynamic-calls-in-dynamic-modules'." + +dynamicallyCallableWithNoSuchMethod: + parameters: + String name: The class name. + problemMessage: "Cannot expose class '#name' because it declares or inherits a 'noSuchMethod' declaration." + correctionMessage: "Try removing the 'noSuchMethod' declaration or not exposing the class." + +dynamicallyCallableWithNoSuchMethodHostSubtype: + parameters: + String name: The class name. + problemMessage: "Cannot expose class '#name' because it has a subtype with a 'noSuchMethod' declaration." + correctionMessage: "Try removing the 'noSuchMethod' declaration from the subtype or not exposing the class." + +classWithNoSuchMethodSubtypeCause: + parameters: + String name: The class name. + problemMessage: "Subtype '#name' implements 'noSuchMethod' here." + +dynamicallyCallableWithNoSuchMethodDynamicSubtype: + parameters: + String name: The class name. + String subtype: The subclass class name. + problemMessage: "Cannot define 'noSuchMethod' on '#subtype' because it is a subtype of '#name', which was exposed as dynamically-callable." + correctionMessage: "Try removing the 'noSuchMethod' declaration or no longer expose '#name' as dynamically-callable." constructorShouldBeListedAsCallableInDynamicInterface: parameters: diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt index 6188f8cd237..34a63ccb4cf 100644 --- a/pkg/front_end/test/spell_checking_list_code.txt +++ b/pkg/front_end/test/spell_checking_list_code.txt @@ -320,6 +320,7 @@ compilations compiler's complement complementary +complements completers completes complexity @@ -1161,6 +1162,7 @@ mocking mockito modelled modelling +modularly modulename momentarily monomorphic @@ -1677,6 +1679,7 @@ selectively selectors semantically semver +sensitive separation separators sequencing diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt index b0612c4434f..1feea0ce3ad 100644 --- a/pkg/front_end/test/spell_checking_list_common.txt +++ b/pkg/front_end/test/spell_checking_list_common.txt @@ -940,6 +940,7 @@ discard discarded discarding discards +discouraged discover discovered discovery @@ -1003,6 +1004,7 @@ duration during dust dynamic +dynamically each eagerly earlier @@ -1197,8 +1199,10 @@ exporter exporters exporting exports +expose exposed exposes +exposing expressed expression expressions @@ -1845,6 +1849,7 @@ listen listener listener's listeners +listing lists literal literal's diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt index d7ea16c0df4..a39de4d4569 100644 --- a/pkg/front_end/test/spell_checking_list_messages.txt +++ b/pkg/front_end/test/spell_checking_list_messages.txt @@ -129,6 +129,7 @@ r re refutable resource +risks sdksummary separators size diff --git a/pkg/front_end/test/testing/suite.dart b/pkg/front_end/test/testing/suite.dart index ea1fb159bb6..afac5aa76f4 100644 --- a/pkg/front_end/test/testing/suite.dart +++ b/pkg/front_end/test/testing/suite.dart @@ -844,6 +844,8 @@ CompilationSetup createCompilationSetup( ..omitOsMessageForTesting = true ..packagesFileUri = packagesFileUri ..dynamicInterfaceSpecificationUri = dynamicInterfaceSpecificationUri + ..allowDynamicCallsInDynamicModules = + dynamicInterfaceSpecificationUri != null ..target = createTarget(folderOptions, context) ..verify = // TODO(johnniwinther): Enable verification in outline and modular diff --git a/pkg/front_end/testcases/general/dynamic_modules/dynamic_interface.yaml b/pkg/front_end/testcases/general/dynamic_modules/dynamic_interface.yaml index e9f828f2273..51811c5abc1 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/dynamic_interface.yaml +++ b/pkg/front_end/testcases/general/dynamic_modules/dynamic_interface.yaml @@ -16,8 +16,12 @@ extendable: class: 'C6' - library: 'main_lib1.dart' class: 'C7' + - library: 'main_lib1.dart' + class: ['C26', 'M3'] - library: 'dart:core' class: 'Object' + - library: 'main_lib5.dart' + class: 'Lib5C1' can-be-overridden: - library: 'main_lib1.dart' @@ -26,6 +30,9 @@ can-be-overridden: - library: 'main_lib1.dart' class: 'C4' member: 'field2' + - library: 'dart:core' + class: 'Object' + member: 'noSuchMethod' callable: - library: 'dart:core' @@ -88,6 +95,11 @@ callable: - library: 'main_lib2.dart' - library: 'main_lib1.dart' class: ['C15', 'C16'] + - library: 'main_lib1.dart' + class: ['C26', 'M3'] + - library: 'main_lib5.dart' + class: 'Lib5C1' + member: '' can-be-used-as-type: - library: 'main_lib1.dart' @@ -99,3 +111,34 @@ can-be-used-as-type: - library: 'main_lib1.dart' extension_type: ['ExtType11', 'ExtType12'] - library: 'main_lib4.dart' + +dynamically-callable: + - library: 'main_lib1.dart' + class: 'C17' + - library: 'main_lib1.dart' + class: 'C18' + member: 'dcMethod3' + - library: 'main_lib1.dart' + class: 'C18' + member: 'dcMethod4' + - library: 'main_lib1.dart' + class: 'C18' + member: 'get:dcGetter2' + - library: 'main_lib1.dart' + class: 'C18' + member: 'set:dcSetter2' + - library: 'main_lib1.dart' + class: 'C18' + member: 'dcField1' + - library: 'main_lib1.dart' + class: 'C18' + member: 'dcField2' + - library: 'main_lib1.dart' + class: 'C19' + - library: 'main_lib1.dart' + class: 'C21' + - library: 'main_lib1.dart' + class: 'C22' + - library: 'main_lib1.dart' + class: 'C24' + - library: 'main_lib5.dart' diff --git a/pkg/front_end/testcases/general/dynamic_modules/main.dart b/pkg/front_end/testcases/general/dynamic_modules/main.dart index 8f24f5eeb91..ec9db0ad90a 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main.dart +++ b/pkg/front_end/testcases/general/dynamic_modules/main.dart @@ -5,6 +5,7 @@ import 'main_lib1.dart'; import 'main_lib2.dart'; import 'main_lib4.dart'; +import 'main_lib5.dart'; dynamic x; @@ -65,7 +66,7 @@ class C7Ext extends C7 { } void test() { - // Dynamic uses are not allowed. + // Dynamic uses are not allowed except for dynamically-callable members. x.foo().bar.baz = 42; if (x case < 3) { print('<3'); @@ -247,4 +248,38 @@ void testCanBeUsedAsType(Object? o) { final inferredList = [C15(), C16()]; } +void testDynamicallyCallable() { + // Allowed, C17 exposed as a whole. + x.dcMethod1(); + x.dcMethod2('a', 2); + x.dcGetter1; + x.dcSetter1 = 42; + // Allowed, C18 members exposed individually. + x.dcMethod3(); + x.dcMethod4('a', 2); + x.dcGetter2; + x.dcSetter2 = 42; + x.dcField1; + x.dcField2; + x.dcField2 = 42; + // Not allowed - getter was not exposed because field is final. + x.dcField1 = 42; + // Allowed - exposed via library + x.dcField5; + x.dcField5 = 42; + x.dcMethod5(); + + C26WithM3().method6(); +} + void main() {} + +// Child class that attempts to override noSuchMethod on a dynamically-callable +// class. +class Lib5WithNSM extends Lib5C1 { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +// Mixin transformation that copies a dynamic call to a private member. +class C26WithM3 extends C26 with M3 {} diff --git a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.expect b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.expect index 27242ab0244..323be45b1b0 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.expect +++ b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.expect @@ -1,7 +1,17 @@ // // Problems in component: // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:12:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart:190:7: Error: Cannot expose class 'C19' because it declares or inherits a 'noSuchMethod' declaration. +// Try removing the 'noSuchMethod' declaration or not exposing the class. +// class C19 { +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart:200:7: Error: Cannot expose class 'C21' because it declares or inherits a 'noSuchMethod' declaration. +// Try removing the 'noSuchMethod' declaration or not exposing the class. +// class C21 extends C20 {} +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:13:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. // Try removing the reference to class 'C3' or update the dynamic interface to list class 'C3' as extendable. // class D3 extends C3 {} // ^ @@ -9,32 +19,32 @@ // pkg/front_end/testcases/general/dynamic_modules/main.dart: Error: Cannot invoke constructor 'C3' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C3' as callable. // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:21:12: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:22:12: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // int? get field1 => null; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:17:8: Error: Cannot override member 'C4.method1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:18:8: Error: Cannot override member 'C4.method1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.method1' as can-be-overridden. // void method1() {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:22:7: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:23:7: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // set field1(int? value) {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:29:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:30:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. // Try removing the reference to class 'C3' or update the dynamic interface to list class 'C3' as extendable. // class E3 implements C3 {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:38:8: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:39:8: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // int? field1; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:34:8: Error: Cannot override member 'C4.method1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:35:8: Error: Cannot override member 'C4.method1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.method1' as can-be-overridden. // void method1() {} // ^ @@ -58,221 +68,241 @@ // pkg/front_end/testcases/general/dynamic_modules/main.dart: Error: Cannot use class '_ConstForC6' as a type in a dynamic module. // Try removing the reference to class '_ConstForC6' or update the dynamic interface to list class '_ConstForC6' as can-be-used-as-type. // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:44:7: Error: Cannot extend, implement or mix-in class 'M1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:279:7: Error: Cannot define 'noSuchMethod' on 'Lib5WithNSM' because it is a subtype of 'Lib5C1', which was exposed as dynamically-callable. +// Try removing the 'noSuchMethod' declaration or no longer expose 'Lib5C1' as dynamically-callable. +// class Lib5WithNSM extends Lib5C1 { +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:45:7: Error: Cannot extend, implement or mix-in class 'M1' in a dynamic module. // Try removing the reference to class 'M1' or update the dynamic interface to list class 'M1' as extendable. // class F1 with M1 {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:15: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart: Warning: Dynamic calls are discouraged in dynamic modules as they may fail at runtime if their target is not properly exposed as 'dynamically-callable'. +// Consider avoiding dynamic calls. You can remove '--allow-dynamic-calls-in-dynamic-modules' to see where dynamic calls are used. +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:15: Error: Dynamic call to selector 'set:baz' is not allowed in a dynamic module. +// Try listing 'set:baz' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:11: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:11: Error: Dynamic call to selector 'get:bar' is not allowed in a dynamic module. +// Try listing 'get:bar' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:5: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:5: Error: Dynamic call to selector 'foo' is not allowed in a dynamic module. +// Try listing 'foo' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:14: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:71:14: Error: Dynamic call to selector '<' is not allowed in a dynamic module. +// Try listing '<' as 'dynamically-callable' in the dynamic interface specification. // if (x case < 3) { // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:74:21: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:75:21: Error: Dynamic call to selector 'get:foo' is not allowed in a dynamic module. +// Try listing 'get:foo' as 'dynamically-callable' in the dynamic interface specification. // case dynamic(foo: 42): // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:80:6: Error: Cannot use class 'C1' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:6: Error: Cannot use class 'C1' as a type in a dynamic module. // Try removing the reference to class 'C1' or update the dynamic interface to list class 'C1' as can-be-used-as-type. // C1 o1 = C1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:80:11: Error: Cannot invoke constructor 'C1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:11: Error: Cannot invoke constructor 'C1' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C1' as callable. // C1 o1 = C1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:6: Error: Cannot invoke member 'C1.method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:82:6: Error: Cannot invoke member 'C1.method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method1' as callable. // o1.method1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:82:12: Error: Cannot invoke member 'C1.method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:83:12: Error: Cannot invoke member 'C1.method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method1' as callable. // print(o1.method1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:83:12: Error: Cannot invoke member 'C1.getter1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:84:12: Error: Cannot invoke member 'C1.getter1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.getter1' as callable. // print(o1.getter1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:84:6: Error: Cannot invoke member 'C1.setter1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:85:6: Error: Cannot invoke member 'C1.setter1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.setter1' as callable. // o1.setter1 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:85:6: Error: Cannot invoke member 'C1.method2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:86:6: Error: Cannot invoke member 'C1.method2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method2' as callable. // C1.method2(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:86:12: Error: Cannot invoke member 'C1.method2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:87:12: Error: Cannot invoke member 'C1.method2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method2' as callable. // print(C1.method2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:87:12: Error: Cannot invoke member 'C1.getter2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:88:12: Error: Cannot invoke member 'C1.getter2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.getter2' as callable. // print(C1.getter2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:88:6: Error: Cannot invoke member 'C1.setter2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:89:6: Error: Cannot invoke member 'C1.setter2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.setter2' as callable. // C1.setter2 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:89:9: Error: Cannot invoke constructor 'C1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:90:9: Error: Cannot invoke constructor 'C1' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C1' as callable. // print(C1.new); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:90:12: Error: Cannot invoke member 'C1.field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:91:12: Error: Cannot invoke member 'C1.field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.field1' as callable. // print(o1.field1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:91:12: Error: Cannot invoke member 'C1.field2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:92:12: Error: Cannot invoke member 'C1.field2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.field2' as callable. // print(C1.field2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:108:3: Error: Cannot invoke member 'method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:109:3: Error: Cannot invoke member 'method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'method1' as callable. // method1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:109:9: Error: Cannot invoke member 'method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:110:9: Error: Cannot invoke member 'method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'method1' as callable. // print(method1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:116:9: Error: Cannot invoke member 'field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:117:9: Error: Cannot invoke member 'field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'field1' as callable. // print(field1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:117:3: Error: Cannot invoke member 'field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:118:3: Error: Cannot invoke member 'field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'field1' as callable. // field1 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:125:12: Error: Cannot invoke member 'C8.fact1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:126:12: Error: Cannot invoke member 'C8.fact1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact1' as callable. // print(C8.fact1()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:126:12: Error: Cannot invoke member 'C8.fact2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:127:12: Error: Cannot invoke member 'C8.fact2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact2' as callable. // print(C8.fact2()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:127:15: Error: Cannot invoke member 'C8.fact4' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:128:15: Error: Cannot invoke member 'C8.fact4' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact4' as callable. // print(const C8.fact4()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:135:9: Error: Cannot use extension type 'ExtType1' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:136:9: Error: Cannot use extension type 'ExtType1' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType1' or update the dynamic interface to list extension type 'ExtType1' as can-be-used-as-type. // print(ExtType1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:136:9: Error: Cannot invoke member 'ExtType1.new' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:137:9: Error: Cannot invoke member 'ExtType1.new' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType1.new' as callable. // print(ExtType1(42)); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:137:12: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:138:12: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'Ext1.isPositive' as callable. // print(42.isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:157:17: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:158:17: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'Ext1.isPositive' as callable. // print(Ext1(1).isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:166:9: Error: Cannot use extension type 'ExtType5' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:167:9: Error: Cannot use extension type 'ExtType5' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType5' or update the dynamic interface to list extension type 'ExtType5' as can-be-used-as-type. // print(ExtType5); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:172:27: Error: Cannot invoke member 'ExtType5.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:173:27: Error: Cannot invoke member 'ExtType5.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType5.isPositive' as callable. // print(ExtType5.plus1(3).isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:235:9: Error: Cannot invoke constructor 'C10' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:236:9: Error: Cannot invoke constructor 'C10' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C10' as callable. // print(C10()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:236:9: Error: Cannot invoke member 'ExtType10.new' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:237:9: Error: Cannot invoke member 'ExtType10.new' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType10.new' as callable. // print(ExtType10(20)); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:239:5: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:240:5: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // o is C13; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:240:5: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:241:5: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // o as C13; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:241:13: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:242:13: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // List list9; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:242:9: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:243:9: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // print(C13); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:243:14: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:244:14: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // print([]); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:244:20: Error: Cannot use extension type 'ExtType13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:245:20: Error: Cannot use extension type 'ExtType13' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType13' or update the dynamic interface to list extension type 'ExtType13' as can-be-used-as-type. // print([]); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:247:9: Error: Cannot use class 'C14' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:248:9: Error: Cannot use class 'C14' as a type in a dynamic module. // Try removing the reference to class 'C14' or update the dynamic interface to list class 'C14' as can-be-used-as-type. // final inferredList = [C15(), C16()]; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:247:24: Error: Cannot use class 'C14' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:248:24: Error: Cannot use class 'C14' as a type in a dynamic module. // Try removing the reference to class 'C14' or update the dynamic interface to list class 'C14' as can-be-used-as-type. // final inferredList = [C15(), C16()]; // ^ // +// pkg/front_end/testcases/general/dynamic_modules/main.dart:266:5: Error: Dynamic call to selector 'set:dcField1' is not allowed in a dynamic module. +// Try listing 'set:dcField1' as 'dynamically-callable' in the dynamic interface specification. +// x.dcField1 = 42; +// ^ +// library; import self as self; import "main_lib1.dart" as mai; import "dart:core" as core; -import "main_lib3.dart" as mai2; -import "main_lib4.dart" as mai3; +import "main_lib5.dart" as mai2; +import "main_lib3.dart" as mai3; +import "main_lib4.dart" as mai4; import "org-dartlang-testcase:///main_lib1.dart"; import "org-dartlang-testcase:///main_lib2.dart"; import "org-dartlang-testcase:///main_lib4.dart"; +import "org-dartlang-testcase:///main_lib5.dart"; class D3 extends mai::C3 { synthetic constructor •() → self::D3 @@ -336,6 +366,19 @@ class C7Ext extends mai::C7 { : super mai::C7::•(param: param) ; } +class Lib5WithNSM extends mai2::Lib5C1 { + synthetic constructor •() → self::Lib5WithNSM + : super mai2::Lib5C1::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C26WithM3 extends self::_C26WithM3&C26&M3 { + synthetic constructor •() → self::C26WithM3 + : super self::_C26WithM3&C26&M3::•() + ; +} abstract class _F1&Object&M1 = core::Object with mai::M1 /*isAnonymousMixin,hasConstConstructor*/ { const synthetic constructor •() → self::_F1&Object&M1 : super core::Object::•() @@ -353,22 +396,29 @@ abstract class _Impl2&Object&Mixin = core::Object with mai::Mixin /*isAnonymousM synthetic mixin-super-stub method foo() → void return super.{mai::Mixin::foo}(); } +abstract class _C26WithM3&C26&M3 = mai::C26 with mai::M3 /*isAnonymousMixin*/ { + synthetic constructor •() → self::_C26WithM3&C26&M3 + : super mai::C26::•() + ; + synthetic mixin-super-stub method method6() → core::int + return super.{mai::M3::method6}(); +} static field dynamic x; static method test() → void { self::x{dynamic}.foo(){dynamic}.bar.{dynamic}baz = 42; { final synthesized dynamic #0#0 = self::x; - final const synthesized core::int #0#1 = #C5; - if(#0#0{dynamic}.<(#C5) as core::bool) { + final const synthesized core::int #0#1 = #C6; + if(#0#0{dynamic}.<(#C6) as core::bool) { core::print("<3"); } } #L1: { final synthesized dynamic #1#0 = self::x; - final const synthesized core::int #1#3 = #C6; + final const synthesized core::int #1#3 = #C7; { - if(#1#0 is dynamic && #C6 =={core::num::==}{(core::Object) → core::bool} #1#0{dynamic}.foo) { + if(#1#0 is dynamic && #C7 =={core::num::==}{(core::Object) → core::bool} #1#0{dynamic}.foo) { { core::print("dyn"); break #L1; @@ -386,10 +436,10 @@ static method test() → void { core::print(o1.{mai::C1::getter1}{core::int}); o1.{mai::C1::setter1} = 42; mai::C1::method2(); - core::print(#C7); + core::print(#C8); core::print(mai::C1::getter2); mai::C1::setter2 = 42; - core::print(#C8); + core::print(#C9); core::print(o1.{mai::C1::field1}{core::int}); core::print(mai::C1::field2); mai::C2 o2 = new mai::C2::•(); @@ -398,36 +448,36 @@ static method test() → void { core::print(o2.{mai::C2::getter1}{core::int}); o2.{mai::C2::setter1} = 42; mai::C2::method2(); - core::print(#C9); + core::print(#C10); core::print(mai::C2::getter2); mai::C2::setter2 = 42; - core::print(#C10); + core::print(#C11); core::print(o2.{mai::C2::field1}{core::int}); core::print(mai::C2::field2); mai::method1(); - core::print(#C11); - mai::method2(); core::print(#C12); + mai::method2(); + core::print(#C13); core::print(mai::field1); mai::field1 = 42; core::print(mai::field2); mai::field2 = 42; core::print(new mai::C8::•()); core::print(mai::C8::fact3()); - core::print(#C13); + core::print(#C14); core::print(new mai::C9::•()); core::print(mai::C9::fact3()); - core::print(#C14); core::print(#C15); + core::print(#C16); core::print(mai::ExtType1|constructor#(42)); core::print(mai::Ext1|get#isPositive(42)); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType2|constructor#(42)); core::print(mai::ExtType2|get#isPositive(mai::ExtType2|constructor#(42))); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType3|constructor#(42)); core::print(mai::ExtType3|get#isPositive(mai::ExtType3|constructor#(42))); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType4|constructor#(42)); core::print(mai::ExtType4|get#isPositive(mai::ExtType4|constructor#(42))); core::print(mai::Ext2|get#isNegative2(1)); @@ -437,67 +487,85 @@ static method test() → void { core::print(mai::Ext1|get#isPositive(1)); core::print(mai::Ext5|get#isNegative5(1)); core::print(mai::Ext5|get#isNegative5(1)); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType5|constructor#plus1(3)); core::print(mai::ExtType5|get#isPositive(mai::ExtType5|constructor#plus1(3))); - core::print(new mai2::Lib3Class::•()); - mai2::lib3Method(); - mai2::lib3Field = 42; - core::print(#C15); - core::print(mai2::Lib3ExtType|constructor#(42)); - core::print(mai2::Lib3Ext|get#lib3IsPositive(42)); + core::print(new mai3::Lib3Class::•()); + mai3::lib3Method(); + mai3::lib3Field = 42; + core::print(#C16); + core::print(mai3::Lib3ExtType|constructor#(42)); + core::print(mai3::Lib3Ext|get#lib3IsPositive(42)); } static method testCanBeUsedAsType(core::Object? o) → void { o is mai::C10; o as mai::C10; core::List list1; - core::print(#C16); + core::print(#C17); core::print([]); o{mai::C10} is mai::ExtType10% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType10% /* erasure=core::int, declared=! */; core::List list2; - core::print(#C15); + core::print(#C16); core::print([]); o{mai::C10} is mai::C11; o{mai::C10} as mai::C11; core::List list3; - core::print(#C17); + core::print(#C18); core::print([]); o{mai::C10} is mai::ExtType11% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType11% /* erasure=core::int, declared=! */; core::List list4; - core::print(#C15); + core::print(#C16); core::print([]); o{mai::C10} is mai::C12; o{mai::C10} as mai::C12; core::List list5; - core::print(#C18); + core::print(#C19); core::print([]); o{mai::C10} is mai::ExtType12% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType12% /* erasure=core::int, declared=! */; core::List list6; - core::print(#C15); + core::print(#C16); core::print([]); - o{mai::C10} is mai3::Lib4Class; - o{mai::C10} as mai3::Lib4Class; - core::List list7; - core::print(#C19); - core::print([]); - o{mai::C10} is mai3::Lib4ExtType% /* erasure=core::int, declared=! */; - o{mai::C10} as mai3::Lib4ExtType% /* erasure=core::int, declared=! */; - core::List list8; - core::print(#C15); - core::print([]); + o{mai::C10} is mai4::Lib4Class; + o{mai::C10} as mai4::Lib4Class; + core::List list7; + core::print(#C20); + core::print([]); + o{mai::C10} is mai4::Lib4ExtType% /* erasure=core::int, declared=! */; + o{mai::C10} as mai4::Lib4ExtType% /* erasure=core::int, declared=! */; + core::List list8; + core::print(#C16); + core::print([]); core::print(new mai::C10::•()); core::print(mai::ExtType10|constructor#(20)); o{mai::C10} is mai::C13; o{mai::C10} as mai::C13; core::List list9; - core::print(#C20); + core::print(#C21); core::print([]); core::print([]); final core::List inferredList = [new mai::C15::•(), new mai::C16::•()]; } +static method testDynamicallyCallable() → void { + self::x{dynamic}.dcMethod1(); + self::x{dynamic}.dcMethod2("a", 2); + self::x{dynamic}.dcGetter1; + self::x.{dynamic}dcSetter1 = 42; + self::x{dynamic}.dcMethod3(); + self::x{dynamic}.dcMethod4("a", 2); + self::x{dynamic}.dcGetter2; + self::x.{dynamic}dcSetter2 = 42; + self::x{dynamic}.dcField1; + self::x{dynamic}.dcField2; + self::x.{dynamic}dcField2 = 42; + self::x.{dynamic}dcField1 = 42; + self::x{dynamic}.dcField5; + self::x.{dynamic}dcField5 = 42; + self::x{dynamic}.dcMethod5(); + new self::C26WithM3::•().{self::_C26WithM3&C26&M3::method6}(){() → core::int}; +} static method main() → void {} library; @@ -660,6 +728,86 @@ class C16 extends core::Object implements mai::C14 { : super core::Object::•() ; } +class C17 extends core::Object { + synthetic constructor •() → mai::C17 + : super core::Object::•() + ; + method dcMethod1() → void {} + method dcMethod2(core::String x, core::int y) → void {} + get dcGetter1() → core::int + return 1; + set dcSetter1(core::int value) → void {} +} +class C18 extends core::Object { + final field core::int dcField1 = 1; + field core::int dcField2 = 1; + synthetic constructor •() → mai::C18 + : super core::Object::•() + ; + method dcMethod3() → void {} + method dcMethod4(core::String x, core::int y) → void {} + get dcGetter2() → core::int + return 1; + set dcSetter2(core::int value) → void {} +} +class C19 extends core::Object { + synthetic constructor •() → mai::C19 + : super core::Object::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C20 extends core::Object { + synthetic constructor •() → mai::C20 + : super core::Object::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C21 extends mai::C20 { + synthetic constructor •() → mai::C21 + : super mai::C20::•() + ; +} +class C22 extends core::Object { + synthetic constructor •() → mai::C22 + : super core::Object::•() + ; +} +class C23 extends mai::C22 { + synthetic constructor •() → mai::C23 + : super mai::C22::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C24 extends core::Object { + synthetic constructor •() → mai::C24 + : super core::Object::•() + ; +} +class C25 extends core::Object implements mai::C24 { + synthetic constructor •() → mai::C25 + : super core::Object::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C26 extends core::Object { + synthetic constructor •() → mai::C26 + : super core::Object::•() + ; + method _privateMethod1() → core::int + return 1; +} +abstract class M3 extends mai::C26 /*isMixinDeclaration*/ { + method method6() → core::int + return (this as dynamic){dynamic}._privateMethod1() as{TypeError,ForDynamic} core::int; +} extension Ext1 on core::int { get isPositive = mai::Ext1|get#isPositive; } @@ -728,8 +876,8 @@ extension type ExtType13(core::int raw) { } static field core::int field1 = 4; static field core::int field2 = 4; -static const field mai::_C5 const1 = #C22; -static const field mai::_C5 const2 = #C24; +static const field mai::_C5 const1 = #C23; +static const field mai::_C5 const2 = #C25; static method method1() → void {} static method method2() → void {} static method _privateMethod1() → void {} @@ -818,91 +966,105 @@ static extension-type-member synthetic method ExtType13|constructor#_#new#tearOf library; import self as self2; -import "main_lib3.dart" as mai2; -additionalExports = (mai2::Lib3Class, - mai2::lib3Method, - mai2::lib3Field, - mai2::lib3Field, - mai2::Lib3ExtType, - mai2::Lib3Ext) +import "main_lib3.dart" as mai3; +additionalExports = (mai3::Lib3Class, + mai3::lib3Method, + mai3::lib3Field, + mai3::lib3Field, + mai3::Lib3ExtType, + mai3::Lib3Ext) export "org-dartlang-testcase:///main_lib3.dart"; library; -import self as mai2; +import self as mai3; import "dart:core" as core; class Lib3Class extends core::Object { - synthetic constructor •() → mai2::Lib3Class + synthetic constructor •() → mai3::Lib3Class : super core::Object::•() ; } extension Lib3Ext on core::int { - get lib3IsPositive = mai2::Lib3Ext|get#lib3IsPositive; + get lib3IsPositive = mai3::Lib3Ext|get#lib3IsPositive; } extension type Lib3ExtType(core::int raw) { abstract extension-type-member representation-field get raw() → core::int; - constructor • = mai2::Lib3ExtType|constructor#; - constructor tearoff • = mai2::Lib3ExtType|constructor#_#new#tearOff; + constructor • = mai3::Lib3ExtType|constructor#; + constructor tearoff • = mai3::Lib3ExtType|constructor#_#new#tearOff; } static field core::int? lib3Field; static method lib3Method() → void {} -static extension-type-member method Lib3ExtType|constructor#(initializing-formal core::int raw) → mai2::Lib3ExtType% /* erasure=core::int, declared=! */ { - lowered final mai2::Lib3ExtType% /* erasure=core::int, declared=! */ #this = raw; +static extension-type-member method Lib3ExtType|constructor#(initializing-formal core::int raw) → mai3::Lib3ExtType% /* erasure=core::int, declared=! */ { + lowered final mai3::Lib3ExtType% /* erasure=core::int, declared=! */ #this = raw; return #this; } -static extension-type-member synthetic method Lib3ExtType|constructor#_#new#tearOff(core::int raw) → mai2::Lib3ExtType% /* erasure=core::int, declared=! */ - return mai2::Lib3ExtType|constructor#(raw); +static extension-type-member synthetic method Lib3ExtType|constructor#_#new#tearOff(core::int raw) → mai3::Lib3ExtType% /* erasure=core::int, declared=! */ + return mai3::Lib3ExtType|constructor#(raw); static extension-member method Lib3Ext|get#lib3IsPositive(lowered final core::int #this) → core::bool return #this.{core::num::>}(0){(core::num) → core::bool}; library; -import self as mai3; +import self as mai4; import "dart:core" as core; class Lib4Class extends core::Object { - synthetic constructor •() → mai3::Lib4Class + synthetic constructor •() → mai4::Lib4Class : super core::Object::•() ; } extension type Lib4ExtType(core::int raw) { abstract extension-type-member representation-field get raw() → core::int; - constructor • = mai3::Lib4ExtType|constructor#; - constructor tearoff • = mai3::Lib4ExtType|constructor#_#new#tearOff; + constructor • = mai4::Lib4ExtType|constructor#; + constructor tearoff • = mai4::Lib4ExtType|constructor#_#new#tearOff; } -static extension-type-member method Lib4ExtType|constructor#(initializing-formal core::int raw) → mai3::Lib4ExtType% /* erasure=core::int, declared=! */ { - lowered final mai3::Lib4ExtType% /* erasure=core::int, declared=! */ #this = raw; +static extension-type-member method Lib4ExtType|constructor#(initializing-formal core::int raw) → mai4::Lib4ExtType% /* erasure=core::int, declared=! */ { + lowered final mai4::Lib4ExtType% /* erasure=core::int, declared=! */ #this = raw; return #this; } -static extension-type-member synthetic method Lib4ExtType|constructor#_#new#tearOff(core::int raw) → mai3::Lib4ExtType% /* erasure=core::int, declared=! */ - return mai3::Lib4ExtType|constructor#(raw); +static extension-type-member synthetic method Lib4ExtType|constructor#_#new#tearOff(core::int raw) → mai4::Lib4ExtType% /* erasure=core::int, declared=! */ + return mai4::Lib4ExtType|constructor#(raw); + +library; +import self as mai2; +import "dart:core" as core; + +class Lib5C1 extends core::Object { + field core::int? dcField5 = null; + synthetic constructor •() → mai2::Lib5C1 + : super core::Object::•() + ; + method dcMethod5() → void {} +} +static field core::int? g1 = 0; constants { #C1 = static-tearoff mai::_privateMethodForC6 #C2 = mai::_ConstForC6 {_f:#C1} #C3 = static-tearoff mai::_privateMethodForC7 #C4 = mai::_ConstForC7 {_f:#C3} - #C5 = 3 - #C6 = 42 - #C7 = static-tearoff mai::C1::method2 - #C8 = constructor-tearoff mai::C1::• - #C9 = static-tearoff mai::C2::method2 - #C10 = constructor-tearoff mai::C2::• - #C11 = static-tearoff mai::method1 - #C12 = static-tearoff mai::method2 - #C13 = mai::C8 {} - #C14 = mai::C9 {} - #C15 = TypeLiteralConstant(core::int) - #C16 = TypeLiteralConstant(mai::C10) - #C17 = TypeLiteralConstant(mai::C11) - #C18 = TypeLiteralConstant(mai::C12) - #C19 = TypeLiteralConstant(mai3::Lib4Class) - #C20 = TypeLiteralConstant(mai::C13) - #C21 = static-tearoff mai::_privateMethod1 - #C22 = mai::_C5 {func:#C21} - #C23 = static-tearoff mai::_privateMethod2 - #C24 = mai::_C5 {func:#C23} + #C5 = core::_Override {} + #C6 = 3 + #C7 = 42 + #C8 = static-tearoff mai::C1::method2 + #C9 = constructor-tearoff mai::C1::• + #C10 = static-tearoff mai::C2::method2 + #C11 = constructor-tearoff mai::C2::• + #C12 = static-tearoff mai::method1 + #C13 = static-tearoff mai::method2 + #C14 = mai::C8 {} + #C15 = mai::C9 {} + #C16 = TypeLiteralConstant(core::int) + #C17 = TypeLiteralConstant(mai::C10) + #C18 = TypeLiteralConstant(mai::C11) + #C19 = TypeLiteralConstant(mai::C12) + #C20 = TypeLiteralConstant(mai4::Lib4Class) + #C21 = TypeLiteralConstant(mai::C13) + #C22 = static-tearoff mai::_privateMethod1 + #C23 = mai::_C5 {func:#C22} + #C24 = static-tearoff mai::_privateMethod2 + #C25 = mai::_C5 {func:#C24} } diff --git a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.modular.expect b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.modular.expect index 735c554df7b..eb35dc5c5a8 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.modular.expect +++ b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.modular.expect @@ -1,7 +1,17 @@ // // Problems in component: // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:12:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart:190:7: Error: Cannot expose class 'C19' because it declares or inherits a 'noSuchMethod' declaration. +// Try removing the 'noSuchMethod' declaration or not exposing the class. +// class C19 { +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart:200:7: Error: Cannot expose class 'C21' because it declares or inherits a 'noSuchMethod' declaration. +// Try removing the 'noSuchMethod' declaration or not exposing the class. +// class C21 extends C20 {} +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:13:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. // Try removing the reference to class 'C3' or update the dynamic interface to list class 'C3' as extendable. // class D3 extends C3 {} // ^ @@ -9,32 +19,32 @@ // pkg/front_end/testcases/general/dynamic_modules/main.dart: Error: Cannot invoke constructor 'C3' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C3' as callable. // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:21:12: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:22:12: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // int? get field1 => null; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:17:8: Error: Cannot override member 'C4.method1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:18:8: Error: Cannot override member 'C4.method1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.method1' as can-be-overridden. // void method1() {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:22:7: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:23:7: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // set field1(int? value) {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:29:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:30:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. // Try removing the reference to class 'C3' or update the dynamic interface to list class 'C3' as extendable. // class E3 implements C3 {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:38:8: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:39:8: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // int? field1; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:34:8: Error: Cannot override member 'C4.method1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:35:8: Error: Cannot override member 'C4.method1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.method1' as can-be-overridden. // void method1() {} // ^ @@ -55,221 +65,241 @@ // pkg/front_end/testcases/general/dynamic_modules/main.dart: Error: Cannot invoke member '_privateMethodForC6' from a dynamic module. // Try removing the call or update the dynamic interface to list member '_privateMethodForC6' as callable. // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:44:7: Error: Cannot extend, implement or mix-in class 'M1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:279:7: Error: Cannot define 'noSuchMethod' on 'Lib5WithNSM' because it is a subtype of 'Lib5C1', which was exposed as dynamically-callable. +// Try removing the 'noSuchMethod' declaration or no longer expose 'Lib5C1' as dynamically-callable. +// class Lib5WithNSM extends Lib5C1 { +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:45:7: Error: Cannot extend, implement or mix-in class 'M1' in a dynamic module. // Try removing the reference to class 'M1' or update the dynamic interface to list class 'M1' as extendable. // class F1 with M1 {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:15: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart: Warning: Dynamic calls are discouraged in dynamic modules as they may fail at runtime if their target is not properly exposed as 'dynamically-callable'. +// Consider avoiding dynamic calls. You can remove '--allow-dynamic-calls-in-dynamic-modules' to see where dynamic calls are used. +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:15: Error: Dynamic call to selector 'set:baz' is not allowed in a dynamic module. +// Try listing 'set:baz' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:11: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:11: Error: Dynamic call to selector 'get:bar' is not allowed in a dynamic module. +// Try listing 'get:bar' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:5: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:5: Error: Dynamic call to selector 'foo' is not allowed in a dynamic module. +// Try listing 'foo' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:14: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:71:14: Error: Dynamic call to selector '<' is not allowed in a dynamic module. +// Try listing '<' as 'dynamically-callable' in the dynamic interface specification. // if (x case < 3) { // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:74:21: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:75:21: Error: Dynamic call to selector 'get:foo' is not allowed in a dynamic module. +// Try listing 'get:foo' as 'dynamically-callable' in the dynamic interface specification. // case dynamic(foo: 42): // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:80:6: Error: Cannot use class 'C1' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:6: Error: Cannot use class 'C1' as a type in a dynamic module. // Try removing the reference to class 'C1' or update the dynamic interface to list class 'C1' as can-be-used-as-type. // C1 o1 = C1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:80:11: Error: Cannot invoke constructor 'C1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:11: Error: Cannot invoke constructor 'C1' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C1' as callable. // C1 o1 = C1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:6: Error: Cannot invoke member 'C1.method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:82:6: Error: Cannot invoke member 'C1.method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method1' as callable. // o1.method1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:82:12: Error: Cannot invoke member 'C1.method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:83:12: Error: Cannot invoke member 'C1.method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method1' as callable. // print(o1.method1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:83:12: Error: Cannot invoke member 'C1.getter1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:84:12: Error: Cannot invoke member 'C1.getter1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.getter1' as callable. // print(o1.getter1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:84:6: Error: Cannot invoke member 'C1.setter1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:85:6: Error: Cannot invoke member 'C1.setter1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.setter1' as callable. // o1.setter1 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:85:6: Error: Cannot invoke member 'C1.method2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:86:6: Error: Cannot invoke member 'C1.method2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method2' as callable. // C1.method2(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:86:12: Error: Cannot invoke member 'C1.method2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:87:12: Error: Cannot invoke member 'C1.method2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method2' as callable. // print(C1.method2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:87:12: Error: Cannot invoke member 'C1.getter2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:88:12: Error: Cannot invoke member 'C1.getter2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.getter2' as callable. // print(C1.getter2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:88:6: Error: Cannot invoke member 'C1.setter2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:89:6: Error: Cannot invoke member 'C1.setter2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.setter2' as callable. // C1.setter2 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:89:9: Error: Cannot invoke constructor 'C1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:90:9: Error: Cannot invoke constructor 'C1' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C1' as callable. // print(C1.new); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:90:12: Error: Cannot invoke member 'C1.field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:91:12: Error: Cannot invoke member 'C1.field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.field1' as callable. // print(o1.field1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:91:12: Error: Cannot invoke member 'C1.field2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:92:12: Error: Cannot invoke member 'C1.field2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.field2' as callable. // print(C1.field2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:108:3: Error: Cannot invoke member 'method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:109:3: Error: Cannot invoke member 'method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'method1' as callable. // method1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:109:9: Error: Cannot invoke member 'method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:110:9: Error: Cannot invoke member 'method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'method1' as callable. // print(method1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:116:9: Error: Cannot invoke member 'field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:117:9: Error: Cannot invoke member 'field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'field1' as callable. // print(field1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:117:3: Error: Cannot invoke member 'field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:118:3: Error: Cannot invoke member 'field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'field1' as callable. // field1 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:125:12: Error: Cannot invoke member 'C8.fact1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:126:12: Error: Cannot invoke member 'C8.fact1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact1' as callable. // print(C8.fact1()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:126:12: Error: Cannot invoke member 'C8.fact2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:127:12: Error: Cannot invoke member 'C8.fact2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact2' as callable. // print(C8.fact2()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:127:15: Error: Cannot invoke member 'C8.fact4' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:128:15: Error: Cannot invoke member 'C8.fact4' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact4' as callable. // print(const C8.fact4()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:135:9: Error: Cannot use extension type 'ExtType1' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:136:9: Error: Cannot use extension type 'ExtType1' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType1' or update the dynamic interface to list extension type 'ExtType1' as can-be-used-as-type. // print(ExtType1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:136:9: Error: Cannot invoke member 'ExtType1.new' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:137:9: Error: Cannot invoke member 'ExtType1.new' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType1.new' as callable. // print(ExtType1(42)); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:137:12: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:138:12: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'Ext1.isPositive' as callable. // print(42.isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:157:17: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:158:17: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'Ext1.isPositive' as callable. // print(Ext1(1).isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:166:9: Error: Cannot use extension type 'ExtType5' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:167:9: Error: Cannot use extension type 'ExtType5' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType5' or update the dynamic interface to list extension type 'ExtType5' as can-be-used-as-type. // print(ExtType5); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:172:27: Error: Cannot invoke member 'ExtType5.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:173:27: Error: Cannot invoke member 'ExtType5.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType5.isPositive' as callable. // print(ExtType5.plus1(3).isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:235:9: Error: Cannot invoke constructor 'C10' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:236:9: Error: Cannot invoke constructor 'C10' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C10' as callable. // print(C10()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:236:9: Error: Cannot invoke member 'ExtType10.new' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:237:9: Error: Cannot invoke member 'ExtType10.new' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType10.new' as callable. // print(ExtType10(20)); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:239:5: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:240:5: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // o is C13; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:240:5: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:241:5: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // o as C13; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:241:13: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:242:13: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // List list9; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:242:9: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:243:9: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // print(C13); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:243:14: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:244:14: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // print([]); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:244:20: Error: Cannot use extension type 'ExtType13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:245:20: Error: Cannot use extension type 'ExtType13' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType13' or update the dynamic interface to list extension type 'ExtType13' as can-be-used-as-type. // print([]); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:247:9: Error: Cannot use class 'C14' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:248:9: Error: Cannot use class 'C14' as a type in a dynamic module. // Try removing the reference to class 'C14' or update the dynamic interface to list class 'C14' as can-be-used-as-type. // final inferredList = [C15(), C16()]; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:247:24: Error: Cannot use class 'C14' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:248:24: Error: Cannot use class 'C14' as a type in a dynamic module. // Try removing the reference to class 'C14' or update the dynamic interface to list class 'C14' as can-be-used-as-type. // final inferredList = [C15(), C16()]; // ^ // +// pkg/front_end/testcases/general/dynamic_modules/main.dart:266:5: Error: Dynamic call to selector 'set:dcField1' is not allowed in a dynamic module. +// Try listing 'set:dcField1' as 'dynamically-callable' in the dynamic interface specification. +// x.dcField1 = 42; +// ^ +// library; import self as self; import "main_lib1.dart" as mai; import "dart:core" as core; -import "main_lib3.dart" as mai2; -import "main_lib4.dart" as mai3; +import "main_lib5.dart" as mai2; +import "main_lib3.dart" as mai3; +import "main_lib4.dart" as mai4; import "org-dartlang-testcase:///main_lib1.dart"; import "org-dartlang-testcase:///main_lib2.dart"; import "org-dartlang-testcase:///main_lib4.dart"; +import "org-dartlang-testcase:///main_lib5.dart"; class D3 extends mai::C3 { synthetic constructor •() → self::D3 @@ -333,6 +363,19 @@ class C7Ext extends mai::C7 { : super mai::C7::•(param: param) ; } +class Lib5WithNSM extends mai2::Lib5C1 { + synthetic constructor •() → self::Lib5WithNSM + : super mai2::Lib5C1::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C26WithM3 extends self::_C26WithM3&C26&M3 { + synthetic constructor •() → self::C26WithM3 + : super self::_C26WithM3&C26&M3::•() + ; +} abstract class _F1&Object&M1 = core::Object with mai::M1 /*isAnonymousMixin,hasConstConstructor*/ { const synthetic constructor •() → self::_F1&Object&M1 : super core::Object::•() @@ -350,22 +393,29 @@ abstract class _Impl2&Object&Mixin = core::Object with mai::Mixin /*isAnonymousM synthetic mixin-super-stub method foo() → void return super.{mai::Mixin::foo}(); } +abstract class _C26WithM3&C26&M3 = mai::C26 with mai::M3 /*isAnonymousMixin*/ { + synthetic constructor •() → self::_C26WithM3&C26&M3 + : super mai::C26::•() + ; + synthetic mixin-super-stub method method6() → core::int + return super.{mai::M3::method6}(); +} static field dynamic x; static method test() → void { self::x{dynamic}.foo(){dynamic}.bar.{dynamic}baz = 42; { final synthesized dynamic #0#0 = self::x; - final const synthesized core::int #0#1 = #C5; - if(#0#0{dynamic}.<(#C5) as core::bool) { + final const synthesized core::int #0#1 = #C6; + if(#0#0{dynamic}.<(#C6) as core::bool) { core::print("<3"); } } #L1: { final synthesized dynamic #1#0 = self::x; - final const synthesized core::int #1#3 = #C6; + final const synthesized core::int #1#3 = #C7; { - if(#1#0 is dynamic && #C6 =={core::num::==}{(core::Object) → core::bool} #1#0{dynamic}.foo) { + if(#1#0 is dynamic && #C7 =={core::num::==}{(core::Object) → core::bool} #1#0{dynamic}.foo) { { core::print("dyn"); break #L1; @@ -383,10 +433,10 @@ static method test() → void { core::print(o1.{mai::C1::getter1}{core::int}); o1.{mai::C1::setter1} = 42; mai::C1::method2(); - core::print(#C7); + core::print(#C8); core::print(mai::C1::getter2); mai::C1::setter2 = 42; - core::print(#C8); + core::print(#C9); core::print(o1.{mai::C1::field1}{core::int}); core::print(mai::C1::field2); mai::C2 o2 = new mai::C2::•(); @@ -395,36 +445,36 @@ static method test() → void { core::print(o2.{mai::C2::getter1}{core::int}); o2.{mai::C2::setter1} = 42; mai::C2::method2(); - core::print(#C9); + core::print(#C10); core::print(mai::C2::getter2); mai::C2::setter2 = 42; - core::print(#C10); + core::print(#C11); core::print(o2.{mai::C2::field1}{core::int}); core::print(mai::C2::field2); mai::method1(); - core::print(#C11); - mai::method2(); core::print(#C12); + mai::method2(); + core::print(#C13); core::print(mai::field1); mai::field1 = 42; core::print(mai::field2); mai::field2 = 42; core::print(new mai::C8::•()); core::print(mai::C8::fact3()); - core::print(#C13); + core::print(#C14); core::print(new mai::C9::•()); core::print(mai::C9::fact3()); - core::print(#C14); core::print(#C15); + core::print(#C16); core::print(mai::ExtType1|constructor#(42)); core::print(mai::Ext1|get#isPositive(42)); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType2|constructor#(42)); core::print(mai::ExtType2|get#isPositive(mai::ExtType2|constructor#(42))); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType3|constructor#(42)); core::print(mai::ExtType3|get#isPositive(mai::ExtType3|constructor#(42))); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType4|constructor#(42)); core::print(mai::ExtType4|get#isPositive(mai::ExtType4|constructor#(42))); core::print(mai::Ext2|get#isNegative2(1)); @@ -434,67 +484,85 @@ static method test() → void { core::print(mai::Ext1|get#isPositive(1)); core::print(mai::Ext5|get#isNegative5(1)); core::print(mai::Ext5|get#isNegative5(1)); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType5|constructor#plus1(3)); core::print(mai::ExtType5|get#isPositive(mai::ExtType5|constructor#plus1(3))); - core::print(new mai2::Lib3Class::•()); - mai2::lib3Method(); - mai2::lib3Field = 42; - core::print(#C15); - core::print(mai2::Lib3ExtType|constructor#(42)); - core::print(mai2::Lib3Ext|get#lib3IsPositive(42)); + core::print(new mai3::Lib3Class::•()); + mai3::lib3Method(); + mai3::lib3Field = 42; + core::print(#C16); + core::print(mai3::Lib3ExtType|constructor#(42)); + core::print(mai3::Lib3Ext|get#lib3IsPositive(42)); } static method testCanBeUsedAsType(core::Object? o) → void { o is mai::C10; o as mai::C10; core::List list1; - core::print(#C16); + core::print(#C17); core::print([]); o{mai::C10} is mai::ExtType10% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType10% /* erasure=core::int, declared=! */; core::List list2; - core::print(#C15); + core::print(#C16); core::print([]); o{mai::C10} is mai::C11; o{mai::C10} as mai::C11; core::List list3; - core::print(#C17); + core::print(#C18); core::print([]); o{mai::C10} is mai::ExtType11% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType11% /* erasure=core::int, declared=! */; core::List list4; - core::print(#C15); + core::print(#C16); core::print([]); o{mai::C10} is mai::C12; o{mai::C10} as mai::C12; core::List list5; - core::print(#C18); + core::print(#C19); core::print([]); o{mai::C10} is mai::ExtType12% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType12% /* erasure=core::int, declared=! */; core::List list6; - core::print(#C15); + core::print(#C16); core::print([]); - o{mai::C10} is mai3::Lib4Class; - o{mai::C10} as mai3::Lib4Class; - core::List list7; - core::print(#C19); - core::print([]); - o{mai::C10} is mai3::Lib4ExtType% /* erasure=core::int, declared=! */; - o{mai::C10} as mai3::Lib4ExtType% /* erasure=core::int, declared=! */; - core::List list8; - core::print(#C15); - core::print([]); + o{mai::C10} is mai4::Lib4Class; + o{mai::C10} as mai4::Lib4Class; + core::List list7; + core::print(#C20); + core::print([]); + o{mai::C10} is mai4::Lib4ExtType% /* erasure=core::int, declared=! */; + o{mai::C10} as mai4::Lib4ExtType% /* erasure=core::int, declared=! */; + core::List list8; + core::print(#C16); + core::print([]); core::print(new mai::C10::•()); core::print(mai::ExtType10|constructor#(20)); o{mai::C10} is mai::C13; o{mai::C10} as mai::C13; core::List list9; - core::print(#C20); + core::print(#C21); core::print([]); core::print([]); final core::List inferredList = [new mai::C15::•(), new mai::C16::•()]; } +static method testDynamicallyCallable() → void { + self::x{dynamic}.dcMethod1(); + self::x{dynamic}.dcMethod2("a", 2); + self::x{dynamic}.dcGetter1; + self::x.{dynamic}dcSetter1 = 42; + self::x{dynamic}.dcMethod3(); + self::x{dynamic}.dcMethod4("a", 2); + self::x{dynamic}.dcGetter2; + self::x.{dynamic}dcSetter2 = 42; + self::x{dynamic}.dcField1; + self::x{dynamic}.dcField2; + self::x.{dynamic}dcField2 = 42; + self::x.{dynamic}dcField1 = 42; + self::x{dynamic}.dcField5; + self::x.{dynamic}dcField5 = 42; + self::x{dynamic}.dcMethod5(); + new self::C26WithM3::•().{self::_C26WithM3&C26&M3::method6}(){() → core::int}; +} static method main() → void {} constants { @@ -502,22 +570,23 @@ constants { #C2 = mai::_ConstForC6 {_f:#C1} #C3 = static-tearoff mai::_privateMethodForC7 #C4 = mai::_ConstForC7 {_f:#C3} - #C5 = 3 - #C6 = 42 - #C7 = static-tearoff mai::C1::method2 - #C8 = constructor-tearoff mai::C1::• - #C9 = static-tearoff mai::C2::method2 - #C10 = constructor-tearoff mai::C2::• - #C11 = static-tearoff mai::method1 - #C12 = static-tearoff mai::method2 - #C13 = mai::C8 {} - #C14 = mai::C9 {} - #C15 = TypeLiteralConstant(core::int) - #C16 = TypeLiteralConstant(mai::C10) - #C17 = TypeLiteralConstant(mai::C11) - #C18 = TypeLiteralConstant(mai::C12) - #C19 = TypeLiteralConstant(mai3::Lib4Class) - #C20 = TypeLiteralConstant(mai::C13) + #C5 = core::_Override {} + #C6 = 3 + #C7 = 42 + #C8 = static-tearoff mai::C1::method2 + #C9 = constructor-tearoff mai::C1::• + #C10 = static-tearoff mai::C2::method2 + #C11 = constructor-tearoff mai::C2::• + #C12 = static-tearoff mai::method1 + #C13 = static-tearoff mai::method2 + #C14 = mai::C8 {} + #C15 = mai::C9 {} + #C16 = TypeLiteralConstant(core::int) + #C17 = TypeLiteralConstant(mai::C10) + #C18 = TypeLiteralConstant(mai::C11) + #C19 = TypeLiteralConstant(mai::C12) + #C20 = TypeLiteralConstant(mai4::Lib4Class) + #C21 = TypeLiteralConstant(mai::C13) } diff --git a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.outline.expect b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.outline.expect index a740af86a36..f7ea959302b 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.outline.expect +++ b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.outline.expect @@ -2,10 +2,12 @@ library; import self as self; import "main_lib1.dart" as mai; import "dart:core" as core; +import "main_lib5.dart" as mai2; import "org-dartlang-testcase:///main_lib1.dart"; import "org-dartlang-testcase:///main_lib2.dart"; import "org-dartlang-testcase:///main_lib4.dart"; +import "org-dartlang-testcase:///main_lib5.dart"; class D3 extends mai::C3 { synthetic constructor •() → self::D3 @@ -65,6 +67,17 @@ class C7Ext extends mai::C7 { constructor •({super-initializing-formal core::Object param = const mai::_ConstForC7::•(mai::_privateMethodForC7)}) → self::C7Ext ; } +class Lib5WithNSM extends mai2::Lib5C1 { + synthetic constructor •() → self::Lib5WithNSM + ; + @core::override + method noSuchMethod(core::Invocation invocation) → dynamic + ; +} +class C26WithM3 extends self::_C26WithM3&C26&M3 { + synthetic constructor •() → self::C26WithM3 + ; +} abstract class _F1&Object&M1 = core::Object with mai::M1 /*isAnonymousMixin,hasConstConstructor*/ { const synthetic constructor •() → self::_F1&Object&M1 : super core::Object::•() @@ -82,11 +95,20 @@ abstract class _Impl2&Object&Mixin = core::Object with mai::Mixin /*isAnonymousM synthetic mixin-super-stub method foo() → void return super.{mai::Mixin::foo}(); } +abstract class _C26WithM3&C26&M3 = mai::C26 with mai::M3 /*isAnonymousMixin*/ { + synthetic constructor •() → self::_C26WithM3&C26&M3 + : super mai::C26::•() + ; + synthetic mixin-super-stub method method6() → core::int + return super.{mai::M3::method6}(); +} static field dynamic x; static method test() → void ; static method testCanBeUsedAsType(core::Object? o) → void ; +static method testDynamicallyCallable() → void + ; static method main() → void ; @@ -245,6 +267,82 @@ class C16 extends core::Object implements mai::C14 { synthetic constructor •() → mai::C16 ; } +class C17 extends core::Object { + synthetic constructor •() → mai::C17 + ; + method dcMethod1() → void + ; + method dcMethod2(core::String x, core::int y) → void + ; + get dcGetter1() → core::int + ; + set dcSetter1(core::int value) → void + ; +} +class C18 extends core::Object { + final field core::int dcField1; + field core::int dcField2; + synthetic constructor •() → mai::C18 + ; + method dcMethod3() → void + ; + method dcMethod4(core::String x, core::int y) → void + ; + get dcGetter2() → core::int + ; + set dcSetter2(core::int value) → void + ; +} +class C19 extends core::Object { + synthetic constructor •() → mai::C19 + ; + @core::override + method noSuchMethod(core::Invocation invocation) → dynamic + ; +} +class C20 extends core::Object { + synthetic constructor •() → mai::C20 + ; + @core::override + method noSuchMethod(core::Invocation invocation) → dynamic + ; +} +class C21 extends mai::C20 { + synthetic constructor •() → mai::C21 + ; +} +class C22 extends core::Object { + synthetic constructor •() → mai::C22 + ; +} +class C23 extends mai::C22 { + synthetic constructor •() → mai::C23 + ; + @core::override + method noSuchMethod(core::Invocation invocation) → dynamic + ; +} +class C24 extends core::Object { + synthetic constructor •() → mai::C24 + ; +} +class C25 extends core::Object implements mai::C24 { + synthetic constructor •() → mai::C25 + ; + @core::override + method noSuchMethod(core::Invocation invocation) → dynamic + ; +} +class C26 extends core::Object { + synthetic constructor •() → mai::C26 + ; + method _privateMethod1() → core::int + ; +} +abstract class M3 extends mai::C26 /*isMixinDeclaration*/ { + method method6() → core::int + ; +} extension Ext1 on core::int { get isPositive = mai::Ext1|get#isPositive; } @@ -388,40 +486,40 @@ static extension-type-member synthetic method ExtType13|constructor#_#new#tearOf library; import self as self2; -import "main_lib3.dart" as mai2; -additionalExports = (mai2::Lib3Class, - mai2::lib3Method, - mai2::lib3Field, - mai2::lib3Field, - mai2::Lib3ExtType, - mai2::Lib3Ext) +import "main_lib3.dart" as mai3; +additionalExports = (mai3::Lib3Class, + mai3::lib3Method, + mai3::lib3Field, + mai3::lib3Field, + mai3::Lib3ExtType, + mai3::Lib3Ext) export "org-dartlang-testcase:///main_lib3.dart"; library; -import self as mai2; +import self as mai3; import "dart:core" as core; class Lib3Class extends core::Object { - synthetic constructor •() → mai2::Lib3Class + synthetic constructor •() → mai3::Lib3Class ; } extension Lib3Ext on core::int { - get lib3IsPositive = mai2::Lib3Ext|get#lib3IsPositive; + get lib3IsPositive = mai3::Lib3Ext|get#lib3IsPositive; } extension type Lib3ExtType(core::int raw) { abstract extension-type-member representation-field get raw() → core::int; - constructor • = mai2::Lib3ExtType|constructor#; - constructor tearoff • = mai2::Lib3ExtType|constructor#_#new#tearOff; + constructor • = mai3::Lib3ExtType|constructor#; + constructor tearoff • = mai3::Lib3ExtType|constructor#_#new#tearOff; } static field core::int? lib3Field; static method lib3Method() → void ; -static extension-type-member method Lib3ExtType|constructor#(initializing-formal core::int raw) → mai2::Lib3ExtType% /* erasure=core::int, declared=! */ +static extension-type-member method Lib3ExtType|constructor#(initializing-formal core::int raw) → mai3::Lib3ExtType% /* erasure=core::int, declared=! */ ; -static extension-type-member synthetic method Lib3ExtType|constructor#_#new#tearOff(core::int raw) → mai2::Lib3ExtType% /* erasure=core::int, declared=! */ - return mai2::Lib3ExtType|constructor#(raw); +static extension-type-member synthetic method Lib3ExtType|constructor#_#new#tearOff(core::int raw) → mai3::Lib3ExtType% /* erasure=core::int, declared=! */ + return mai3::Lib3ExtType|constructor#(raw); static extension-member method Lib3Ext|get#lib3IsPositive(lowered final core::int #this) → core::bool ; @@ -443,12 +541,30 @@ static extension-type-member method Lib4ExtType|constructor#(initializing-formal static extension-type-member synthetic method Lib4ExtType|constructor#_#new#tearOff(core::int raw) → self3::Lib4ExtType% /* erasure=core::int, declared=! */ return self3::Lib4ExtType|constructor#(raw); +library; +import self as mai2; +import "dart:core" as core; + +class Lib5C1 extends core::Object { + field core::int? dcField5; + synthetic constructor •() → mai2::Lib5C1 + ; + method dcMethod5() → void + ; +} +static field core::int? g1; + Extra constant evaluation status: -Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:58:16 -> InstanceConstant(const _ConstForC6{_ConstForC6._f: _privateMethodForC6}) -Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:64:16 -> InstanceConstant(const _ConstForC7{_ConstForC7._f: _privateMethodForC7}) +Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:59:16 -> InstanceConstant(const _ConstForC6{_ConstForC6._f: _privateMethodForC6}) +Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:65:16 -> InstanceConstant(const _ConstForC7{_ConstForC7._f: _privateMethodForC7}) +Evaluated: StaticGet @ org-dartlang-testcase:///main.dart:280:4 -> InstanceConstant(const _Override{}) Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main_lib1.dart:78:28 -> InstanceConstant(const _ConstForC6{_ConstForC6._f: _privateMethodForC6}) Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main_lib1.dart:89:28 -> InstanceConstant(const _ConstForC7{_ConstForC7._f: _privateMethodForC7}) +Evaluated: StaticGet @ org-dartlang-testcase:///main_lib1.dart:191:4 -> InstanceConstant(const _Override{}) +Evaluated: StaticGet @ org-dartlang-testcase:///main_lib1.dart:196:4 -> InstanceConstant(const _Override{}) +Evaluated: StaticGet @ org-dartlang-testcase:///main_lib1.dart:205:4 -> InstanceConstant(const _Override{}) +Evaluated: StaticGet @ org-dartlang-testcase:///main_lib1.dart:212:4 -> InstanceConstant(const _Override{}) Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main_lib1.dart:67:16 -> InstanceConstant(const _C5{_C5.func: _privateMethod1}) Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main_lib1.dart:68:16 -> InstanceConstant(const _C5{_C5.func: _privateMethod2}) -Extra constant evaluation: evaluated: 41, effectively constant: 6 +Extra constant evaluation: evaluated: 48, effectively constant: 11 diff --git a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.transformed.expect b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.transformed.expect index 72b6e78c6ae..544b0fde9d9 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general/dynamic_modules/main.dart.strong.transformed.expect @@ -1,7 +1,17 @@ // // Problems in component: // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:12:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart:190:7: Error: Cannot expose class 'C19' because it declares or inherits a 'noSuchMethod' declaration. +// Try removing the 'noSuchMethod' declaration or not exposing the class. +// class C19 { +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart:200:7: Error: Cannot expose class 'C21' because it declares or inherits a 'noSuchMethod' declaration. +// Try removing the 'noSuchMethod' declaration or not exposing the class. +// class C21 extends C20 {} +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:13:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. // Try removing the reference to class 'C3' or update the dynamic interface to list class 'C3' as extendable. // class D3 extends C3 {} // ^ @@ -9,32 +19,32 @@ // pkg/front_end/testcases/general/dynamic_modules/main.dart: Error: Cannot invoke constructor 'C3' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C3' as callable. // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:21:12: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:22:12: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // int? get field1 => null; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:17:8: Error: Cannot override member 'C4.method1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:18:8: Error: Cannot override member 'C4.method1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.method1' as can-be-overridden. // void method1() {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:22:7: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:23:7: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // set field1(int? value) {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:29:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:30:7: Error: Cannot extend, implement or mix-in class 'C3' in a dynamic module. // Try removing the reference to class 'C3' or update the dynamic interface to list class 'C3' as extendable. // class E3 implements C3 {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:38:8: Error: Cannot override member 'C4.field1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:39:8: Error: Cannot override member 'C4.field1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.field1' as can-be-overridden. // int? field1; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:34:8: Error: Cannot override member 'C4.method1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:35:8: Error: Cannot override member 'C4.method1' in a dynamic module. // Try removing the override or update the dynamic interface to list member 'C4.method1' as can-be-overridden. // void method1() {} // ^ @@ -58,221 +68,241 @@ // pkg/front_end/testcases/general/dynamic_modules/main.dart: Error: Cannot use class '_ConstForC6' as a type in a dynamic module. // Try removing the reference to class '_ConstForC6' or update the dynamic interface to list class '_ConstForC6' as can-be-used-as-type. // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:44:7: Error: Cannot extend, implement or mix-in class 'M1' in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:279:7: Error: Cannot define 'noSuchMethod' on 'Lib5WithNSM' because it is a subtype of 'Lib5C1', which was exposed as dynamically-callable. +// Try removing the 'noSuchMethod' declaration or no longer expose 'Lib5C1' as dynamically-callable. +// class Lib5WithNSM extends Lib5C1 { +// ^ +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:45:7: Error: Cannot extend, implement or mix-in class 'M1' in a dynamic module. // Try removing the reference to class 'M1' or update the dynamic interface to list class 'M1' as extendable. // class F1 with M1 {} // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:15: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart: Warning: Dynamic calls are discouraged in dynamic modules as they may fail at runtime if their target is not properly exposed as 'dynamically-callable'. +// Consider avoiding dynamic calls. You can remove '--allow-dynamic-calls-in-dynamic-modules' to see where dynamic calls are used. +// +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:15: Error: Dynamic call to selector 'set:baz' is not allowed in a dynamic module. +// Try listing 'set:baz' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:11: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:11: Error: Dynamic call to selector 'get:bar' is not allowed in a dynamic module. +// Try listing 'get:bar' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:69:5: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:5: Error: Dynamic call to selector 'foo' is not allowed in a dynamic module. +// Try listing 'foo' as 'dynamically-callable' in the dynamic interface specification. // x.foo().bar.baz = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:70:14: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:71:14: Error: Dynamic call to selector '<' is not allowed in a dynamic module. +// Try listing '<' as 'dynamically-callable' in the dynamic interface specification. // if (x case < 3) { // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:74:21: Error: Dynamic calls are not allowed in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:75:21: Error: Dynamic call to selector 'get:foo' is not allowed in a dynamic module. +// Try listing 'get:foo' as 'dynamically-callable' in the dynamic interface specification. // case dynamic(foo: 42): // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:80:6: Error: Cannot use class 'C1' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:6: Error: Cannot use class 'C1' as a type in a dynamic module. // Try removing the reference to class 'C1' or update the dynamic interface to list class 'C1' as can-be-used-as-type. // C1 o1 = C1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:80:11: Error: Cannot invoke constructor 'C1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:11: Error: Cannot invoke constructor 'C1' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C1' as callable. // C1 o1 = C1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:81:6: Error: Cannot invoke member 'C1.method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:82:6: Error: Cannot invoke member 'C1.method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method1' as callable. // o1.method1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:82:12: Error: Cannot invoke member 'C1.method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:83:12: Error: Cannot invoke member 'C1.method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method1' as callable. // print(o1.method1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:83:12: Error: Cannot invoke member 'C1.getter1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:84:12: Error: Cannot invoke member 'C1.getter1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.getter1' as callable. // print(o1.getter1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:84:6: Error: Cannot invoke member 'C1.setter1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:85:6: Error: Cannot invoke member 'C1.setter1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.setter1' as callable. // o1.setter1 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:85:6: Error: Cannot invoke member 'C1.method2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:86:6: Error: Cannot invoke member 'C1.method2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method2' as callable. // C1.method2(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:86:12: Error: Cannot invoke member 'C1.method2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:87:12: Error: Cannot invoke member 'C1.method2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.method2' as callable. // print(C1.method2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:87:12: Error: Cannot invoke member 'C1.getter2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:88:12: Error: Cannot invoke member 'C1.getter2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.getter2' as callable. // print(C1.getter2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:88:6: Error: Cannot invoke member 'C1.setter2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:89:6: Error: Cannot invoke member 'C1.setter2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.setter2' as callable. // C1.setter2 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:89:9: Error: Cannot invoke constructor 'C1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:90:9: Error: Cannot invoke constructor 'C1' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C1' as callable. // print(C1.new); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:90:12: Error: Cannot invoke member 'C1.field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:91:12: Error: Cannot invoke member 'C1.field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.field1' as callable. // print(o1.field1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:91:12: Error: Cannot invoke member 'C1.field2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:92:12: Error: Cannot invoke member 'C1.field2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C1.field2' as callable. // print(C1.field2); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:108:3: Error: Cannot invoke member 'method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:109:3: Error: Cannot invoke member 'method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'method1' as callable. // method1(); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:109:9: Error: Cannot invoke member 'method1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:110:9: Error: Cannot invoke member 'method1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'method1' as callable. // print(method1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:116:9: Error: Cannot invoke member 'field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:117:9: Error: Cannot invoke member 'field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'field1' as callable. // print(field1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:117:3: Error: Cannot invoke member 'field1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:118:3: Error: Cannot invoke member 'field1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'field1' as callable. // field1 = 42; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:125:12: Error: Cannot invoke member 'C8.fact1' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:126:12: Error: Cannot invoke member 'C8.fact1' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact1' as callable. // print(C8.fact1()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:126:12: Error: Cannot invoke member 'C8.fact2' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:127:12: Error: Cannot invoke member 'C8.fact2' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact2' as callable. // print(C8.fact2()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:127:15: Error: Cannot invoke member 'C8.fact4' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:128:15: Error: Cannot invoke member 'C8.fact4' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'C8.fact4' as callable. // print(const C8.fact4()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:135:9: Error: Cannot use extension type 'ExtType1' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:136:9: Error: Cannot use extension type 'ExtType1' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType1' or update the dynamic interface to list extension type 'ExtType1' as can-be-used-as-type. // print(ExtType1); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:136:9: Error: Cannot invoke member 'ExtType1.new' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:137:9: Error: Cannot invoke member 'ExtType1.new' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType1.new' as callable. // print(ExtType1(42)); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:137:12: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:138:12: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'Ext1.isPositive' as callable. // print(42.isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:157:17: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:158:17: Error: Cannot invoke member 'Ext1.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'Ext1.isPositive' as callable. // print(Ext1(1).isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:166:9: Error: Cannot use extension type 'ExtType5' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:167:9: Error: Cannot use extension type 'ExtType5' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType5' or update the dynamic interface to list extension type 'ExtType5' as can-be-used-as-type. // print(ExtType5); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:172:27: Error: Cannot invoke member 'ExtType5.isPositive' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:173:27: Error: Cannot invoke member 'ExtType5.isPositive' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType5.isPositive' as callable. // print(ExtType5.plus1(3).isPositive); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:235:9: Error: Cannot invoke constructor 'C10' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:236:9: Error: Cannot invoke constructor 'C10' from a dynamic module. // Try removing the call or update the dynamic interface to list constructor 'C10' as callable. // print(C10()); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:236:9: Error: Cannot invoke member 'ExtType10.new' from a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:237:9: Error: Cannot invoke member 'ExtType10.new' from a dynamic module. // Try removing the call or update the dynamic interface to list member 'ExtType10.new' as callable. // print(ExtType10(20)); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:239:5: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:240:5: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // o is C13; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:240:5: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:241:5: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // o as C13; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:241:13: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:242:13: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // List list9; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:242:9: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:243:9: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // print(C13); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:243:14: Error: Cannot use class 'C13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:244:14: Error: Cannot use class 'C13' as a type in a dynamic module. // Try removing the reference to class 'C13' or update the dynamic interface to list class 'C13' as can-be-used-as-type. // print([]); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:244:20: Error: Cannot use extension type 'ExtType13' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:245:20: Error: Cannot use extension type 'ExtType13' as a type in a dynamic module. // Try removing the reference to extension type 'ExtType13' or update the dynamic interface to list extension type 'ExtType13' as can-be-used-as-type. // print([]); // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:247:9: Error: Cannot use class 'C14' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:248:9: Error: Cannot use class 'C14' as a type in a dynamic module. // Try removing the reference to class 'C14' or update the dynamic interface to list class 'C14' as can-be-used-as-type. // final inferredList = [C15(), C16()]; // ^ // -// pkg/front_end/testcases/general/dynamic_modules/main.dart:247:24: Error: Cannot use class 'C14' as a type in a dynamic module. +// pkg/front_end/testcases/general/dynamic_modules/main.dart:248:24: Error: Cannot use class 'C14' as a type in a dynamic module. // Try removing the reference to class 'C14' or update the dynamic interface to list class 'C14' as can-be-used-as-type. // final inferredList = [C15(), C16()]; // ^ // +// pkg/front_end/testcases/general/dynamic_modules/main.dart:266:5: Error: Dynamic call to selector 'set:dcField1' is not allowed in a dynamic module. +// Try listing 'set:dcField1' as 'dynamically-callable' in the dynamic interface specification. +// x.dcField1 = 42; +// ^ +// library; import self as self; import "main_lib1.dart" as mai; import "dart:core" as core; -import "main_lib3.dart" as mai2; -import "main_lib4.dart" as mai3; +import "main_lib5.dart" as mai2; +import "main_lib3.dart" as mai3; +import "main_lib4.dart" as mai4; import "org-dartlang-testcase:///main_lib1.dart"; import "org-dartlang-testcase:///main_lib2.dart"; import "org-dartlang-testcase:///main_lib4.dart"; +import "org-dartlang-testcase:///main_lib5.dart"; class D3 extends mai::C3 { synthetic constructor •() → self::D3 @@ -336,6 +366,19 @@ class C7Ext extends mai::C7 { : super mai::C7::•(param: param) ; } +class Lib5WithNSM extends mai2::Lib5C1 { + synthetic constructor •() → self::Lib5WithNSM + : super mai2::Lib5C1::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C26WithM3 extends self::_C26WithM3&C26&M3 { + synthetic constructor •() → self::C26WithM3 + : super self::_C26WithM3&C26&M3::•() + ; +} abstract class _F1&Object&M1 extends core::Object implements mai::M1 /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { const synthetic constructor •() → self::_F1&Object&M1 : super core::Object::•() @@ -352,22 +395,29 @@ abstract class _Impl2&Object&Mixin extends core::Object implements mai::Mixin /* ; method /* from org-dartlang-testcase:///main_lib1.dart */ foo() → void {} } +abstract class _C26WithM3&C26&M3 extends mai::C26 implements mai::M3 /*isAnonymousMixin,isEliminatedMixin*/ { + synthetic constructor •() → self::_C26WithM3&C26&M3 + : super mai::C26::•() + ; + method /* from org-dartlang-testcase:///main_lib1.dart */ method6() → core::int + return (this as dynamic){dynamic}._privateMethod1() as{TypeError,ForDynamic} core::int; +} static field dynamic x; static method test() → void { self::x{dynamic}.foo(){dynamic}.bar.{dynamic}baz = 42; { final synthesized dynamic #0#0 = self::x; - final const synthesized core::int #0#1 = #C5; - if(#0#0{dynamic}.<(#C5) as core::bool) { + final const synthesized core::int #0#1 = #C6; + if(#0#0{dynamic}.<(#C6) as core::bool) { core::print("<3"); } } #L1: { final synthesized dynamic #1#0 = self::x; - final const synthesized core::int #1#3 = #C6; + final const synthesized core::int #1#3 = #C7; { - if(#1#0 is dynamic && #C6 =={core::num::==}{(core::Object) → core::bool} #1#0{dynamic}.foo) { + if(#1#0 is dynamic && #C7 =={core::num::==}{(core::Object) → core::bool} #1#0{dynamic}.foo) { { core::print("dyn"); break #L1; @@ -385,10 +435,10 @@ static method test() → void { core::print(o1.{mai::C1::getter1}{core::int}); o1.{mai::C1::setter1} = 42; mai::C1::method2(); - core::print(#C7); + core::print(#C8); core::print(mai::C1::getter2); mai::C1::setter2 = 42; - core::print(#C8); + core::print(#C9); core::print(o1.{mai::C1::field1}{core::int}); core::print(mai::C1::field2); mai::C2 o2 = new mai::C2::•(); @@ -397,36 +447,36 @@ static method test() → void { core::print(o2.{mai::C2::getter1}{core::int}); o2.{mai::C2::setter1} = 42; mai::C2::method2(); - core::print(#C9); + core::print(#C10); core::print(mai::C2::getter2); mai::C2::setter2 = 42; - core::print(#C10); + core::print(#C11); core::print(o2.{mai::C2::field1}{core::int}); core::print(mai::C2::field2); mai::method1(); - core::print(#C11); - mai::method2(); core::print(#C12); + mai::method2(); + core::print(#C13); core::print(mai::field1); mai::field1 = 42; core::print(mai::field2); mai::field2 = 42; core::print(new mai::C8::•()); core::print(mai::C8::fact3()); - core::print(#C13); + core::print(#C14); core::print(new mai::C9::•()); core::print(mai::C9::fact3()); - core::print(#C14); core::print(#C15); + core::print(#C16); core::print(mai::ExtType1|constructor#(42)); core::print(mai::Ext1|get#isPositive(42)); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType2|constructor#(42)); core::print(mai::ExtType2|get#isPositive(mai::ExtType2|constructor#(42))); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType3|constructor#(42)); core::print(mai::ExtType3|get#isPositive(mai::ExtType3|constructor#(42))); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType4|constructor#(42)); core::print(mai::ExtType4|get#isPositive(mai::ExtType4|constructor#(42))); core::print(mai::Ext2|get#isNegative2(1)); @@ -436,67 +486,85 @@ static method test() → void { core::print(mai::Ext1|get#isPositive(1)); core::print(mai::Ext5|get#isNegative5(1)); core::print(mai::Ext5|get#isNegative5(1)); - core::print(#C15); + core::print(#C16); core::print(mai::ExtType5|constructor#plus1(3)); core::print(mai::ExtType5|get#isPositive(mai::ExtType5|constructor#plus1(3))); - core::print(new mai2::Lib3Class::•()); - mai2::lib3Method(); - mai2::lib3Field = 42; - core::print(#C15); - core::print(mai2::Lib3ExtType|constructor#(42)); - core::print(mai2::Lib3Ext|get#lib3IsPositive(42)); + core::print(new mai3::Lib3Class::•()); + mai3::lib3Method(); + mai3::lib3Field = 42; + core::print(#C16); + core::print(mai3::Lib3ExtType|constructor#(42)); + core::print(mai3::Lib3Ext|get#lib3IsPositive(42)); } static method testCanBeUsedAsType(core::Object? o) → void { o is mai::C10; o as mai::C10; core::List list1; - core::print(#C16); + core::print(#C17); core::print(core::_GrowableList::•(0)); o{mai::C10} is mai::ExtType10% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType10% /* erasure=core::int, declared=! */; core::List list2; - core::print(#C15); + core::print(#C16); core::print(core::_GrowableList::•(0)); o{mai::C10} is mai::C11; o{mai::C10} as mai::C11; core::List list3; - core::print(#C17); + core::print(#C18); core::print(core::_GrowableList::•(0)); o{mai::C10} is mai::ExtType11% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType11% /* erasure=core::int, declared=! */; core::List list4; - core::print(#C15); + core::print(#C16); core::print(core::_GrowableList::•(0)); o{mai::C10} is mai::C12; o{mai::C10} as mai::C12; core::List list5; - core::print(#C18); + core::print(#C19); core::print(core::_GrowableList::•(0)); o{mai::C10} is mai::ExtType12% /* erasure=core::int, declared=! */; o{mai::C10} as mai::ExtType12% /* erasure=core::int, declared=! */; core::List list6; - core::print(#C15); + core::print(#C16); core::print(core::_GrowableList::•(0)); - o{mai::C10} is mai3::Lib4Class; - o{mai::C10} as mai3::Lib4Class; - core::List list7; - core::print(#C19); - core::print(core::_GrowableList::•(0)); - o{mai::C10} is mai3::Lib4ExtType% /* erasure=core::int, declared=! */; - o{mai::C10} as mai3::Lib4ExtType% /* erasure=core::int, declared=! */; - core::List list8; - core::print(#C15); - core::print(core::_GrowableList::•(0)); + o{mai::C10} is mai4::Lib4Class; + o{mai::C10} as mai4::Lib4Class; + core::List list7; + core::print(#C20); + core::print(core::_GrowableList::•(0)); + o{mai::C10} is mai4::Lib4ExtType% /* erasure=core::int, declared=! */; + o{mai::C10} as mai4::Lib4ExtType% /* erasure=core::int, declared=! */; + core::List list8; + core::print(#C16); + core::print(core::_GrowableList::•(0)); core::print(new mai::C10::•()); core::print(mai::ExtType10|constructor#(20)); o{mai::C10} is mai::C13; o{mai::C10} as mai::C13; core::List list9; - core::print(#C20); + core::print(#C21); core::print(core::_GrowableList::•(0)); core::print(core::_GrowableList::•(0)); final core::List inferredList = core::_GrowableList::_literal2(new mai::C15::•(), new mai::C16::•()); } +static method testDynamicallyCallable() → void { + self::x{dynamic}.dcMethod1(); + self::x{dynamic}.dcMethod2("a", 2); + self::x{dynamic}.dcGetter1; + self::x.{dynamic}dcSetter1 = 42; + self::x{dynamic}.dcMethod3(); + self::x{dynamic}.dcMethod4("a", 2); + self::x{dynamic}.dcGetter2; + self::x.{dynamic}dcSetter2 = 42; + self::x{dynamic}.dcField1; + self::x{dynamic}.dcField2; + self::x.{dynamic}dcField2 = 42; + self::x.{dynamic}dcField1 = 42; + self::x{dynamic}.dcField5; + self::x.{dynamic}dcField5 = 42; + self::x{dynamic}.dcMethod5(); + new self::C26WithM3::•().{self::_C26WithM3&C26&M3::method6}(){() → core::int}; +} static method main() → void {} library; @@ -659,6 +727,86 @@ class C16 extends core::Object implements mai::C14 { : super core::Object::•() ; } +class C17 extends core::Object { + synthetic constructor •() → mai::C17 + : super core::Object::•() + ; + method dcMethod1() → void {} + method dcMethod2(core::String x, core::int y) → void {} + get dcGetter1() → core::int + return 1; + set dcSetter1(core::int value) → void {} +} +class C18 extends core::Object { + final field core::int dcField1 = 1; + field core::int dcField2 = 1; + synthetic constructor •() → mai::C18 + : super core::Object::•() + ; + method dcMethod3() → void {} + method dcMethod4(core::String x, core::int y) → void {} + get dcGetter2() → core::int + return 1; + set dcSetter2(core::int value) → void {} +} +class C19 extends core::Object { + synthetic constructor •() → mai::C19 + : super core::Object::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C20 extends core::Object { + synthetic constructor •() → mai::C20 + : super core::Object::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C21 extends mai::C20 { + synthetic constructor •() → mai::C21 + : super mai::C20::•() + ; +} +class C22 extends core::Object { + synthetic constructor •() → mai::C22 + : super core::Object::•() + ; +} +class C23 extends mai::C22 { + synthetic constructor •() → mai::C23 + : super mai::C22::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C24 extends core::Object { + synthetic constructor •() → mai::C24 + : super core::Object::•() + ; +} +class C25 extends core::Object implements mai::C24 { + synthetic constructor •() → mai::C25 + : super core::Object::•() + ; + @#C5 + method noSuchMethod(core::Invocation invocation) → dynamic + return super.{core::Object::noSuchMethod}(invocation); +} +class C26 extends core::Object { + synthetic constructor •() → mai::C26 + : super core::Object::•() + ; + method _privateMethod1() → core::int + return 1; +} +abstract class M3 extends mai::C26 /*isMixinDeclaration*/ { + method method6() → core::int + return (this as dynamic){dynamic}._privateMethod1() as{TypeError,ForDynamic} core::int; +} extension Ext1 on core::int { get isPositive = mai::Ext1|get#isPositive; } @@ -727,8 +875,8 @@ extension type ExtType13(core::int raw) { } static field core::int field1 = 4; static field core::int field2 = 4; -static const field mai::_C5 const1 = #C22; -static const field mai::_C5 const2 = #C24; +static const field mai::_C5 const1 = #C23; +static const field mai::_C5 const2 = #C25; static method method1() → void {} static method method2() → void {} static method _privateMethod1() → void {} @@ -817,91 +965,105 @@ static extension-type-member synthetic method ExtType13|constructor#_#new#tearOf library; import self as self2; -import "main_lib3.dart" as mai2; -additionalExports = (mai2::Lib3Class, - mai2::lib3Method, - mai2::lib3Field, - mai2::lib3Field, - mai2::Lib3ExtType, - mai2::Lib3Ext) +import "main_lib3.dart" as mai3; +additionalExports = (mai3::Lib3Class, + mai3::lib3Method, + mai3::lib3Field, + mai3::lib3Field, + mai3::Lib3ExtType, + mai3::Lib3Ext) export "org-dartlang-testcase:///main_lib3.dart"; library; -import self as mai2; +import self as mai3; import "dart:core" as core; class Lib3Class extends core::Object { - synthetic constructor •() → mai2::Lib3Class + synthetic constructor •() → mai3::Lib3Class : super core::Object::•() ; } extension Lib3Ext on core::int { - get lib3IsPositive = mai2::Lib3Ext|get#lib3IsPositive; + get lib3IsPositive = mai3::Lib3Ext|get#lib3IsPositive; } extension type Lib3ExtType(core::int raw) { abstract extension-type-member representation-field get raw() → core::int; - constructor • = mai2::Lib3ExtType|constructor#; - constructor tearoff • = mai2::Lib3ExtType|constructor#_#new#tearOff; + constructor • = mai3::Lib3ExtType|constructor#; + constructor tearoff • = mai3::Lib3ExtType|constructor#_#new#tearOff; } static field core::int? lib3Field; static method lib3Method() → void {} -static extension-type-member method Lib3ExtType|constructor#(initializing-formal core::int raw) → mai2::Lib3ExtType% /* erasure=core::int, declared=! */ { - lowered final mai2::Lib3ExtType% /* erasure=core::int, declared=! */ #this = raw; +static extension-type-member method Lib3ExtType|constructor#(initializing-formal core::int raw) → mai3::Lib3ExtType% /* erasure=core::int, declared=! */ { + lowered final mai3::Lib3ExtType% /* erasure=core::int, declared=! */ #this = raw; return #this; } -static extension-type-member synthetic method Lib3ExtType|constructor#_#new#tearOff(core::int raw) → mai2::Lib3ExtType% /* erasure=core::int, declared=! */ - return mai2::Lib3ExtType|constructor#(raw); +static extension-type-member synthetic method Lib3ExtType|constructor#_#new#tearOff(core::int raw) → mai3::Lib3ExtType% /* erasure=core::int, declared=! */ + return mai3::Lib3ExtType|constructor#(raw); static extension-member method Lib3Ext|get#lib3IsPositive(lowered final core::int #this) → core::bool return #this.{core::num::>}(0){(core::num) → core::bool}; library; -import self as mai3; +import self as mai4; import "dart:core" as core; class Lib4Class extends core::Object { - synthetic constructor •() → mai3::Lib4Class + synthetic constructor •() → mai4::Lib4Class : super core::Object::•() ; } extension type Lib4ExtType(core::int raw) { abstract extension-type-member representation-field get raw() → core::int; - constructor • = mai3::Lib4ExtType|constructor#; - constructor tearoff • = mai3::Lib4ExtType|constructor#_#new#tearOff; + constructor • = mai4::Lib4ExtType|constructor#; + constructor tearoff • = mai4::Lib4ExtType|constructor#_#new#tearOff; } -static extension-type-member method Lib4ExtType|constructor#(initializing-formal core::int raw) → mai3::Lib4ExtType% /* erasure=core::int, declared=! */ { - lowered final mai3::Lib4ExtType% /* erasure=core::int, declared=! */ #this = raw; +static extension-type-member method Lib4ExtType|constructor#(initializing-formal core::int raw) → mai4::Lib4ExtType% /* erasure=core::int, declared=! */ { + lowered final mai4::Lib4ExtType% /* erasure=core::int, declared=! */ #this = raw; return #this; } -static extension-type-member synthetic method Lib4ExtType|constructor#_#new#tearOff(core::int raw) → mai3::Lib4ExtType% /* erasure=core::int, declared=! */ - return mai3::Lib4ExtType|constructor#(raw); +static extension-type-member synthetic method Lib4ExtType|constructor#_#new#tearOff(core::int raw) → mai4::Lib4ExtType% /* erasure=core::int, declared=! */ + return mai4::Lib4ExtType|constructor#(raw); + +library; +import self as mai2; +import "dart:core" as core; + +class Lib5C1 extends core::Object { + field core::int? dcField5 = null; + synthetic constructor •() → mai2::Lib5C1 + : super core::Object::•() + ; + method dcMethod5() → void {} +} +static field core::int? g1 = 0; constants { #C1 = static-tearoff mai::_privateMethodForC6 #C2 = mai::_ConstForC6 {_f:#C1} #C3 = static-tearoff mai::_privateMethodForC7 #C4 = mai::_ConstForC7 {_f:#C3} - #C5 = 3 - #C6 = 42 - #C7 = static-tearoff mai::C1::method2 - #C8 = constructor-tearoff mai::C1::• - #C9 = static-tearoff mai::C2::method2 - #C10 = constructor-tearoff mai::C2::• - #C11 = static-tearoff mai::method1 - #C12 = static-tearoff mai::method2 - #C13 = mai::C8 {} - #C14 = mai::C9 {} - #C15 = TypeLiteralConstant(core::int) - #C16 = TypeLiteralConstant(mai::C10) - #C17 = TypeLiteralConstant(mai::C11) - #C18 = TypeLiteralConstant(mai::C12) - #C19 = TypeLiteralConstant(mai3::Lib4Class) - #C20 = TypeLiteralConstant(mai::C13) - #C21 = static-tearoff mai::_privateMethod1 - #C22 = mai::_C5 {func:#C21} - #C23 = static-tearoff mai::_privateMethod2 - #C24 = mai::_C5 {func:#C23} + #C5 = core::_Override {} + #C6 = 3 + #C7 = 42 + #C8 = static-tearoff mai::C1::method2 + #C9 = constructor-tearoff mai::C1::• + #C10 = static-tearoff mai::C2::method2 + #C11 = constructor-tearoff mai::C2::• + #C12 = static-tearoff mai::method1 + #C13 = static-tearoff mai::method2 + #C14 = mai::C8 {} + #C15 = mai::C9 {} + #C16 = TypeLiteralConstant(core::int) + #C17 = TypeLiteralConstant(mai::C10) + #C18 = TypeLiteralConstant(mai::C11) + #C19 = TypeLiteralConstant(mai::C12) + #C20 = TypeLiteralConstant(mai4::Lib4Class) + #C21 = TypeLiteralConstant(mai::C13) + #C22 = static-tearoff mai::_privateMethod1 + #C23 = mai::_C5 {func:#C22} + #C24 = static-tearoff mai::_privateMethod2 + #C25 = mai::_C5 {func:#C24} } diff --git a/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline.expect index b1a5b87801e..c73adc11d37 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline.expect +++ b/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline.expect @@ -4,6 +4,8 @@ import 'main_lib2.dart'; import 'main_lib4.dart'; +import 'main_lib5.dart'; + dynamic x; class D3 extends C3 {} @@ -46,4 +48,13 @@ void test() {} void testCanBeUsedAsType(Object? o) {} +void testDynamicallyCallable() {} + void main() {} + +class Lib5WithNSM extends Lib5C1 { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +class C26WithM3 extends C26 with M3 {} diff --git a/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline_modelled.expect index 5a77a014a95..b41b827a852 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline_modelled.expect +++ b/pkg/front_end/testcases/general/dynamic_modules/main.dart.textual_outline_modelled.expect @@ -1,6 +1,9 @@ import 'main_lib1.dart'; import 'main_lib2.dart'; import 'main_lib4.dart'; +import 'main_lib5.dart'; + +class C26WithM3 extends C26 with M3 {} class C6Ext extends C6 { C6Ext({super.param}); @@ -38,6 +41,11 @@ class Impl1 extends Base implements Interface {} class Impl2 with Mixin implements Interface {} +class Lib5WithNSM extends Lib5C1 { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + dynamic x; void main() {} @@ -45,3 +53,5 @@ void main() {} void test() {} void testCanBeUsedAsType(Object? o) {} + +void testDynamicallyCallable() {} diff --git a/pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart b/pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart index 84dd143e431..c8437de23d1 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart +++ b/pkg/front_end/testcases/general/dynamic_modules/main_lib1.dart @@ -167,3 +167,56 @@ class C14 {} // Not exposed class C15 implements C14 {} class C16 implements C14 {} + +// Dynamically callable class +class C17 { + void dcMethod1() {} + void dcMethod2(String x, int y) {} + int get dcGetter1 => 1; + void set dcSetter1(int value) {} +} + +// Dynamically callable members +class C18 { + 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 C19 { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +class C20 { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +class C21 extends C20 {} + +class C22 {} + +class C23 extends C22 { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +class C24 {} + +class C25 implements C24 { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +class C26 { + int _privateMethod1() => 1; +} + +mixin M3 on C26 { + int method6() => (this as dynamic)._privateMethod1(); +} diff --git a/pkg/front_end/testcases/general/dynamic_modules/main_lib5.dart b/pkg/front_end/testcases/general/dynamic_modules/main_lib5.dart new file mode 100644 index 00000000000..b43ffbb881a --- /dev/null +++ b/pkg/front_end/testcases/general/dynamic_modules/main_lib5.dart @@ -0,0 +1,10 @@ +// 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 Lib5C1 { + int? dcField5; + void dcMethod5() {} +} + +int? g1 = 0; diff --git a/pkg/front_end/testcases/general/dynamic_modules/test.options b/pkg/front_end/testcases/general/dynamic_modules/test.options index fe370d2d22d..e6f2c563b25 100644 --- a/pkg/front_end/testcases/general/dynamic_modules/test.options +++ b/pkg/front_end/testcases/general/dynamic_modules/test.options @@ -3,3 +3,4 @@ main_lib1.dart main_lib2.dart main_lib3.dart main_lib4.dart +main_lib5.dart diff --git a/pkg/vm/dynamic_interface.md b/pkg/vm/dynamic_interface.md index c31da9f4863..2687333cf3b 100644 --- a/pkg/vm/dynamic_interface.md +++ b/pkg/vm/dynamic_interface.md @@ -21,6 +21,11 @@ callable: ... - item N +dynamically-callable: + - item 1 + ... + - item N + extendable: - item 1 ... @@ -41,6 +46,11 @@ can-be-used-as-type: called from dynamic module and classes which can be referenced in types of dynamic module. +`dynamically-callable` section specifies methods and properties +which can be called from a dynamic module using dynamic calls. A +dynamic call to a members exposed as `callable` but not +`dynamically-callable` will fail at runtime. + `extendable` section specifies classes which dynamic module can be extend, mix-in or implement.