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
Remove native keyword, replace with @native annotation #5979
Comments
Set owner to @rakudrama. |
Marked this as being blocked by #9850. |
Added TriageForM5 label. |
Removed TriageForM5 label. |
Removed this from the Later milestone. |
We have removed 'native' from class declarations.
T foo() native; can be replaced by external T foo(); The compiler needs to be fixed to recognize an 'external instance method of a native class' as a native instance method. Important details that need to be retained: (a) Types in the declaration (or annotations) drive compiler knowledge of instantiated types and the insertion of conversions. The other cases are used only in tests:
void setup() native '''js-code'''; We can't quite replace this with: void setup() { The problem is that the code from JS-forms is included in minification, but test cases rely on the original naming of internal functions in 'js-code'. This is probably best handled by a new annotation: @JSBody(r'''js-code''')
T foo() native; This is used in tests to access globals assigned in the js-code of the examples above. Can be replaced with: import 'dart:_foreign_helper' show JS; Note that in some cases the JS-form will require returns: and creates: in the first argument string. There are some other cases with fake Dart bodies. These tests should be upgraded to avoid the old frog syntax. Set owner to @johnniwinther. |
I would prefer to keep the semantics of 'external' to be that the implementation is provided in terms of patching. Therefore I propose the following encodings:
@Returns('T') When patching is used: In the origin file: external T foo(); In the patch file: @patch @JSBody(r'''js-code''') |
I disagree with #7. We should avoid providing fake and incorrect bodies. It make the code harder to process by tools (for example, some inference by the tool may conclude it has no effects or always returns null). 'external' is the correct language marker to use for methods that have implementations not written in Dart. |
The patch mechanism isn't part of the Dart language. As far as I know, the external keyword was added to also cover the suggestion in #6. However, we want both dart2js and the VM to read the same library files (origin file), but have different patch files. For this reason, it seems suboptimal to put the @native annotation in the shared library definition (origin file). Another reason for strictly separating dart2js implementation details from the origin files is reflection. Arguably, all annotations in patch files can be omitted from reflection, whereas annotations in origin files must be visible to reflection. I don't understand why all instance methods of native classes of this form: T foo() native; Can't be replaced by: foo() => JS('T_impl', '#.foo()', this); This leads me to the following definition of a native class in the origin file: class NativeClass { No special annotations for dart2js, they are all in the patch file: @patch @native |
Re: #9: Nobody is suggesting putting annotations in the origin file. Yes, you can can replace the specific example: T foo() native; In the general case there are problems that are difficult or error-prone to express or cannot be expressed like this.
T1 foo(CALLBACKTYPE callback) => ? In the IDL we sometimes don't actually know the signature of CALLBACKTYPE. We could list the signature in a table in the generator, but it is safer for dart2js to generate code dependent on the Dart function signature, where we can also enforce other constraints. This enforcement is important so we can detect when the generated libraries require features that we have not yet implemented.
For we generate these stubs on the interceptor, which are different to the usual stubs: foo$0: function (receiver) { return receiver.foo(); }
This is what I am proposing for instance methods: -------- origin file: -------- dart2js patch file: The interceptor for AnElement might contains the following depending on selectors used in the program: foo$0: function (receiver) { return receiver.foo(); } If dart2js can infer or type propagate that x is AnElement, x.foo() is compiled to x.foo() The effort required to implement the above is approximately "Replace the isNative method on FunctionElement with an additional clause 'or is an external method defined on a native class'". |
Removed Oldschool-Milestone-Later label. |
Duplicate of #28791 |
We should try to get rid of our use of the native keyword and instead use @native annotations (perhaps of various kinds).
The text was updated successfully, but these errors were encountered: