-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Need spec and compile-time errors of incorrect JS interop usage #32929
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
Comments
My preference is for the latter: I can imagine we'd have a js-interop checker implemented as a kernel-visitor that we can both share. |
It would be ideal for the analyzer to give errors/warnings before a compilation failure, if possible. (It's not clear to me we have a good strategy yet for web/JS-specific analyzer checks, so maybe we need a thread/doc/discussion about that separate from js-interop checking in the compilation pipeline) |
Yeah for JS interop, we can have shared checks between DDC/dart2js/Analyzer. That way they show up in IDE as well as compilers. At the moment I don't really care where the checks live :) ... I'm mostly concerned that JS interop is completely unchecked and there's all kinds of undefined behavior people can, and do stumble into. (And personally, when I have to touch DDC's implementation code for JS interop, I have no idea what's supposed to be legal or not, so it's really difficult to refactor any of the code that touches that.) |
@vsmenon and I just ran into a client internally with another edge, non-`abstract classes, i.e.: @JS()
library js_interop;
import 'package:js/js.dart';
@JS()
@anonymous
class Animal {
external String get name;
external set name(String name);
} This should probably be a compile-time error, as it implicitly creates a default constructor. The correct implementation would be: @JS()
@anonymous
abstract class Animal {
external String get name;
external set name(String name);
} Or, with an
|
Nitpick: The second class also gets a default constructor, you just can't use it to instantiate the abstract class. You can extend the class, though, which should probably also be disallowed. |
additional checks that we have discussed recently:
|
I'm curious: what's blocking us from allowing instance method renames? I was talking a bit about this last week and figured it would be a good way to wrap overloading. |
The current interop design in dart2js does not allow it - though we can do it easily in ddc. In dart2js all So the renames that work in |
If I recall correctly, I should note that even though the issue is more visible because of dart2js's implementation, there is an actual composition problem here. We allow users to define JS-interop classes without coordination. If two libraries expose the same JS class, they are both allowed and equally usable. Because dart2js dispatches based on the underlying value (in this case JS-instance), it needs to ensure that all JS-interop definitions for that JS class are consistent with each other. Because we want to avoid link-time errors, we enforce this modularly by limiting what the user can do. When we disallow renames (and method bodies among other things), we allow the declarations to be combined without conflict. |
Correct.
Right, that's why we ideally would like a more statically predictable JS interop. If we can trust the calling side then we can do the rename there. That's what the DDC implementation for instance member renames looked like. |
What is the status on this one? |
This one issue is a long arc, and wont fit entirely into the September release, so we will be moving it to the October release soon (likely next week? We can move it now if you prefer). Many checks have landed, and we'll continue to land them before and after the next milestone. |
Adding on to what Siggi said, should we continue to move the milestone until everything we want here has been added? We'll likely continue to add things here and stretch this across multiple milestones. |
Consider making this an Epic, with sub-issue inside it. So each sub-issue can be place in different milestone. Continue rolling this over to the next milestone defeat the purpose of the milestone. |
I agree with making it an Epic. We'll need to break this down into bits that will make sense to include in milestones. |
@srujzs @sigmundch - are we still using this as a tracking issue? If so, it is P1 but no 2021 updates. Should we drop to P2? |
Edit: A lot of these have since spawned their own bugs or we aren't planning on handling, and we're currently use the above epic to track the work. We've kind of treated this as a tracking bug for static checks in the past but also not all of them, so it's a bit messy, which makes me think we should just close this and use the separate issues as needed. @sigmundch and @rileyporter , let me know if you want this reopened. |
There are many invalid things that can be done with JS interop, but we don't have static errors for this.
Here are some examples of things that should be reported (or else, need to be specified and fixed in the DDC/dart2js):
@JS
on a class/library member without a@JS
on the library@JS
on a class member instead ofexternal
@JS
class (Dart code is silently ignored)@JS
classes from a Dart class (also unclear ifimplements
is supported)@JS
classErrors should be reported from Analyzer so people can see the problem sooner. (Once DDC migrates to Kernel, need a way of calling into Analyzer to produce these kinds of errors. Or we just have shared code between dart2js/DDC for validating JS interop usage.)
Also it would be lovely to have a specification. These would be useful:
@JS
allowed to appear?external
allowed to appear?The text was updated successfully, but these errors were encountered: