Skip to content

[ddc] extension type method calls for static interop in expression evaluation fail at runtime #53048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
annagrin opened this issue Jul 26, 2023 · 2 comments
Labels
area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. dev-compiler-eval web-dev-compiler web-eval evaluation support on the web web-js-interop Issues that impact all js interop

Comments

@annagrin
Copy link
Contributor

annagrin commented Jul 26, 2023

Example

// @dart=3.2

@JS()
library debug_static_interop;

import 'dart:async';
import 'dart:js_util';
import 'dart:js_interop';

import 'package:js/js.dart' hide JS;

// The Dart class must have `@JSExport` on it or one of its instance members.
@JSExport()
class Counter {
  int value = 0;
  @JSExport('increment')
  void renamedIncrement() {
    value++;
  }
}

extension type JSCounter(JSObject _) {
  external int get value;
  external void increment();
}

void main() {
  Timer.periodic(const Duration(seconds: 1), (Timer t) {
    var dartCounter = Counter();
    var jsCounter = createDartExport<Counter>(dartCounter) as JSCounter;

    jsCounter.increment();
    dartCounter.renamedIncrement();
   
    print('Dart: ${dartCounter.value}'); // Breakpoint
    print('JS: ${jsCounter.value}');
  });
}

Repro:

  • add a breakpoint on the line commented with // breakpoint
  • try evaluating jsCounter.value

Expected: 1
Actual: TypeError: dart.global.JSCounterView|get#value is not a function

Details:

  • Dart expression jsCounter.value is compiled to
(function(t, dartCounter, jsCounter) {
    const dart_sdk = require('dart_sdk');
const dart = dart_sdk.dart;
    const web__main = require('web/main');
    const main = web__main.web__main;
    return dart.global['JSCounterView|get#value'](jsCounter);
  }(
    t,
    dartCounter,
    jsCounter
  ))

I suspect that

  return dart.global['JSCounterView|get#value'](jsCounter);

should be

  return main['JSCounterView|'](jsCounter).value;
@annagrin annagrin changed the title [ddc] extension type method calls fail at runtime in expression evaluation [ddc] extension type method calls for static interop fail at runtime in expression evaluation Jul 26, 2023
@annagrin annagrin changed the title [ddc] extension type method calls for static interop fail at runtime in expression evaluation [ddc] extension type method calls for static interop in expression evaluation fail at runtime Jul 26, 2023
@annagrin annagrin added the web-js-interop Issues that impact all js interop label Jul 26, 2023
@srujzs
Copy link
Contributor

srujzs commented Jul 26, 2023

The likely culprit here is that js_util_optimizer.dart didn't run on the new expression. DDC sees that it's an external method that hasn't been resolved, and therefore tries to resolve it using package:js-style logic, but it doesn't work.

@mraleph mraleph added the area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. label Aug 3, 2023
@annagrin
Copy link
Contributor Author

annagrin commented Aug 9, 2023

Thanks @srujzs , I think I know what needs to be done now. Will send a PR soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. dev-compiler-eval web-dev-compiler web-eval evaluation support on the web web-js-interop Issues that impact all js interop
Projects
None yet
Development

No branches or pull requests

3 participants