Skip to content

[DDC] JS staticInterop works poorly with variadic arguments, runtime failures #49785

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

Open
matanlurey opened this issue Aug 22, 2022 · 4 comments
Labels
area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. web-js-interop Issues that impact all js interop

Comments

@matanlurey
Copy link
Contributor

Dart SDK version: 2.17.6 (stable) (Tue Jul 12 12:54:37 2022 +0200) on "macos_arm64"


I might have tried to be "too clever" for my own good, but here is what I tried and what happens:

import 'package:js/js.dart';

@JS()
@staticInterop
external JSWindow get window;

@JS()
@staticInterop
abstract class JSWindow {}

extension JSWindow$ on JSWindow {
  external JSConsole get console;
}

@JS('console')
@staticInterop
abstract class JSConsole {}

extension JSConsole$ on JSConsole {
  @JS('log')
  external void log1(Object? a);

  @JS('log')
  external void log2(Object? a, Object? b);

  @JS('log')
  external void log3(Object? a, Object? b, Object? c);

  @JS('log')
  external void log4(Object? a, Object? b, Object? c, Object? d);

  @JS('log')
  external void log5(Object? a, Object? b, Object? c, Object? d, Object? e);
}

Everything compiles (no errors), but at runtime I get:

Uncaught TypeError: dart.global.log is not a function

The generated DDC JS code looks like this:

dart.global.log(dom['JSWindow$|get#console'](dart.global.window), a);

I find this pretty bizarre personally. It works fine like this:

extension JSConsole$ on JSConsole {
  external void log(Object? a);
}

... but then I can only provide a single argument. I tried using optional arguments:

extension JSConsole$ on JSConsole {
  external void log(Object? a, [Object? b, Object? c]);
}

... but then I get null printed in the console for every unused argument.

@a-siva a-siva added the area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. label Aug 22, 2022
@sigmundch
Copy link
Member

@matanlurey - what version of the tools are you using to run these examples?
We haven't been testing things out in webdev much because this is fairly an experimental feature on the side at the moment. But using a local build of ddc and dart2js the examples with logN work for me, also trying it in dartpad works.

We currently implement the extensions as a lowering in the compilers, so both compilers behave the same, but the error you see seems like an error I'd expect when the lowering was not enabled (which could be the case in an older version of the SDK). Unfortunately, I don't believe there is an SDK lower bound on package:js for this.

More generally, we have talked about being more flexible with JS functions and being less strict about arity than we are with Dart functions, for example, to support use cases like #48186.

@sigmundch sigmundch added the web-js-interop Issues that impact all js interop label Aug 22, 2022
@matanlurey
Copy link
Contributor Author

@matanlurey - what version of the tools are you using to run these examples?

You mean the SDK?

Dart SDK version: 2.17.6 (stable) (Tue Jul 12 12:54:37 2022 +0200) on "macos_arm64"

If you're asking about webdev, 2.7.10.

We haven't been testing things out in webdev much because this is fairly an experimental feature on the side at the moment. But using a local build of ddc and dart2js the examples with logN work for me, also trying it in dartpad works.

I guess I'm confused why webdev would change the implementation. Is it possible you're on a newer/bleeding DDC?

We currently implement the extensions as a lowering in the compilers, so both compilers behave the same, but the error you see seems like an error I'd expect when the lowering was not enabled (which could be the case in an older version of the SDK). Unfortunately, I don't believe there is an SDK lower bound on package:js for this.

Sounds good. It's not blocking any work, this is a personal project, I was just surprised.

Happy to wait for the next stable release.

More generally, we have talked about being more flexible with JS functions and being less strict about arity than we are with Dart functions, for example, to support use cases like #48186.

Nice! I ran into this problem as well with window.requestAnimationFrame - I wanted to ignore the timestamp argument.

@sigmundch
Copy link
Member

Thanks!

Technically webdev wouldn't affect things, you are correct, that said, in the past we have seen issues in some modular configurations that don't show up in others (e.g. the incremental front-end server shows issues with a transformer that makes the incremental compiler state invalid for hot restart) - so, as a result, there are issues that sometimes pop up only under certain environments.

I can't quite explain why you saw the runtime errors with dart.global.log. The SDK 2.17.6 should have the compiler transformations in place for @staticInterop so that is surprising. Do you see the same issues when compiling with dart2js?

@matanlurey
Copy link
Contributor Author

I haven't tried, and probably won't if the DDC bits don't work yet. No worries :)

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. web-js-interop Issues that impact all js interop
Projects
None yet
Development

No branches or pull requests

3 participants