diff --git a/lib/src/eval/shared/stdlib/core.dart b/lib/src/eval/shared/stdlib/core.dart index bba1771..b9fe008 100644 --- a/lib/src/eval/shared/stdlib/core.dart +++ b/lib/src/eval/shared/stdlib/core.dart @@ -36,6 +36,7 @@ class DartCorePlugin implements EvalPlugin { void configureForRuntime(Runtime runtime) { configurePrintForRuntime(runtime); $List.configureForRuntime(runtime); + $Iterable.configureForRuntime(runtime); $Duration.configureForRuntime(runtime); $Future.configureForRuntime(runtime); $DateTime.configureForRuntime(runtime); diff --git a/lib/src/eval/shared/stdlib/core/iterable.dart b/lib/src/eval/shared/stdlib/core/iterable.dart index 8a5c315..6f1cdf7 100644 --- a/lib/src/eval/shared/stdlib/core/iterable.dart +++ b/lib/src/eval/shared/stdlib/core/iterable.dart @@ -2,10 +2,23 @@ part of 'collection.dart'; /// dart_eval bimodal wrapper for [Iterable] class $Iterable implements Iterable, $Instance { + /// Configure the [$Iterable] wrapper for use in a [Runtime] + static void configureForRuntime(Runtime runtime) { + runtime.registerBridgeFunc('dart:core', 'Iterable.generate', _$Iterable_generate); + } + /// Compile-time class definition for [$Iterable] static const $declaration = BridgeClassDef( BridgeClassType(BridgeTypeRef(CoreTypes.iterable), generics: {'E': BridgeGenericParam()}), - constructors: {}, + constructors: { + 'generate': BridgeConstructorDef(BridgeFunctionDef( + params: [ + BridgeParameter('count', BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.intType)), false), + BridgeParameter('generator', BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.functionType)), true), + ], + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.iterable, [BridgeTypeRef.ref('E')])), + generics: {'E': BridgeGenericParam()})), + }, methods: { 'join': BridgeMethodDef( BridgeFunctionDef(params: [ @@ -251,3 +264,14 @@ class $Iterable implements Iterable, $Instance { @override int $getRuntimeType(Runtime runtime) => runtime.lookupType(CoreTypes.iterable); } + +$Function get$Iterable_generate(Runtime _) => _$Iterable_generate; + +const _$Iterable_generate = $Function(_Iterable_generate); + +final _defaultIterableGenerator = $Function((runtime, target, args) => args[0]); +$Value? _Iterable_generate(Runtime runtime, $Value? target, List<$Value?> args) { + var generator = args[1] as EvalFunction?; + generator ??= _defaultIterableGenerator; + return $Iterable.wrap(Iterable.generate(args[0]!.$value, (i) => generator!(runtime, target, [$int(i)]))); +} diff --git a/lib/src/eval/shared/stdlib/core/list.dart b/lib/src/eval/shared/stdlib/core/list.dart index 2941495..8bd1d32 100644 --- a/lib/src/eval/shared/stdlib/core/list.dart +++ b/lib/src/eval/shared/stdlib/core/list.dart @@ -640,5 +640,10 @@ $Function get$List_generate(Runtime _) => _$List_generate; const _$List_generate = $Function(_List_generate); $Value? _List_generate(Runtime runtime, $Value? target, List<$Value?> args) { - return $List.wrap(List.generate(args[0]!.$value, args[1]!.$value, growable: args[2]?.$value ?? true)); + final generator = args[1] as EvalFunction; + return $List.wrap( + List.generate(args[0]!.$value, + (i) => generator(runtime, target, [$int(i)]), + growable: args[2]?.$value ?? true), + ); } diff --git a/test/stdlib_test.dart b/test/stdlib_test.dart index d762a85..07d22a4 100644 --- a/test/stdlib_test.dart +++ b/test/stdlib_test.dart @@ -284,5 +284,52 @@ void main() { runtime.executeLib('package:example/main.dart', 'main'); }, prints('7\n')); }); + + test('Iterable.generate', () { + final runtime = compiler.compileWriteAndLoad({ + 'example': { + 'main.dart': ''' + void main() { + print(Iterable.generate(3, (i) => i)); + // check if works for non-integers + print(Iterable.generate(2, (i) => 'test')); + } + ''', + } + }); + expect(() { + runtime.executeLib('package:example/main.dart', 'main'); + }, prints('(0, 1, 2)\n(\$"test", \$"test")\n')); + }); + + test('Iterable.generate without generator', () { + final runtime = compiler.compileWriteAndLoad({ + 'example': { + 'main.dart': ''' + void main() { + print(Iterable.generate(3)); + } + ''', + } + }); + expect(() { + runtime.executeLib('package:example/main.dart', 'main'); + }, prints('(0, 1, 2)\n')); + }); + + test('List.generate', () { + final runtime = compiler.compileWriteAndLoad({ + 'example': { + 'main.dart': ''' + void main() { + print(List.generate(3, (i) => i)); + } + ''', + } + }); + expect(() { + runtime.executeLib('package:example/main.dart', 'main'); + }, prints('[0, 1, 2]\n')); + }); }); }