ethanblake4 / dart_eval

Extensible Dart interpreter for Dart with full interop

Home Page:https://pub.dev/packages/dart_eval

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

type 'int' is not a subtype of type '$Value?'

HXiaoMing opened this issue · comments

Test case:

import 'package:dart_eval/dart_eval.dart';
import 'package:test/test.dart';

import 'wrapper_lib.dart';

void main() {
  group('wrapper tests', () {
    late Compiler compiler;

    setUp(() {
      compiler = Compiler();
    });

    test('Using a wrapper class', () {

      compiler.defineBridgeClasses([
        $TestApiImpl.$declaration,
      ]);

      final program = compiler.compile({
        'example': {
          'main.dart': '''
            import 'package:wrapper_lib/wrapper_lib.dart';
       
            bool main() {
              final testApiImpl = TestApiImpl();
              final intResult = testApiImpl.read(5);
              final stringResult = testApiImpl.read('hi');
              print('read intResult \$intResult, stringResult \$stringResult');
              return true;
            }
          '''
        }
      });

      final runtime = Runtime.ofProgram(program);

      runtime.registerBridgeFunc('package:wrapper_lib/wrapper_lib.dart',
          'TestApiImpl.', $TestApiImpl.$new,
          isBridge: false);

      expect(runtime.executeLib('package:example/main.dart', 'main'), true);
    });

  });
}

wrapper_lib.dart

import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';

class TestApiImpl {
  T read<T>(T value) {
    print('read value $value');
    return value;
  }
}

class $TestApiImpl implements $Instance {
  $TestApiImpl.wrap(this.$value);

  /// Compile-time type reference for [$TestApiImpl]
  static const $type = BridgeTypeRef(
      BridgeTypeSpec('package:wrapper_lib/wrapper_lib.dart', 'TestApiImpl'));

  /// Compile-time bridge declaration for [$TestApiImpl]
  static const $declaration = BridgeClassDef(
      BridgeClassType($type, isAbstract: false),
      constructors: {
        '': BridgeConstructorDef(
            BridgeFunctionDef(returns: BridgeTypeAnnotation($type)))
      },
      methods: {
        'read': BridgeMethodDef(BridgeFunctionDef(
            returns: BridgeTypeAnnotation(BridgeTypeRef.ref('T')),
            params: [
              BridgeParameter(
                  'value', BridgeTypeAnnotation(BridgeTypeRef.ref('T')), false),
            ])),
      },
      wrap: true);

  static $Value? $new(Runtime runtime, $Value? thisValue, List<$Value?> args) {
    return $TestApiImpl.wrap(TestApiImpl());
  }

  late final _superclass = $Object($value);

  @override
  final TestApiImpl $value;

  @override
  TestApiImpl get $reified => $value;

  @override
  $Value? $getProperty(Runtime runtime, String identifier) {
    if (identifier == 'read') {
      return $Function((Runtime rt, $Value? target, List<$Value?> args) {
        return $value.read(args[0]!.$value);
      });
    }
    return _superclass.$getProperty(runtime, identifier);
  }

  @override
  int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!);

  @override
  void $setProperty(Runtime runtime, String identifier, $Value value) {
    return _superclass.$setProperty(runtime, identifier, value);
  }

}

run the test 'Using a wrapper class', occur error: type 'int' is not a subtype of type '$Value?'

package:dart_eval/src/eval/runtime/runtime.dart 830:7 Runtime.execute
package:dart_eval/src/eval/runtime/runtime.dart 810:12 Runtime.executeLib
test/wrapper_test.dart 42:22 main..

type 'int' is not a subtype of type '$Value?'

Replace the line

return $value.read(args[0]!.$value);

with

return rt.wrap($value.read(args[0]!.$value));

Note, this will only work for primitive values like int, String, etc.