Skip to content
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

[linter] proposal: omit_obvious_native_types_in_native_fields_and_functions #59777

Open
halildurmus opened this issue Dec 20, 2024 · 2 comments
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion.

Comments

@halildurmus
Copy link
Contributor

omit_obvious_native_types_in_native_fields_and_functions

Description

Omit the native type in the @Native annotation when it can be inferred from the annotated declaration.

Details

The @Native annotation in dart:ffi is used to link native fields or functions to Dart code.

With the changes introduced in https://dart-review.googlesource.com/c/sdk/+/400840, the native type for functions annotated with @Native can now be inferred directly from their Dart signatures. (This capability already existed for fields.) As a result, explicitly specifying the native type is unnecessary in some cases, which helps make the code cleaner and more concise.

Adding a lint to promote omitting redundant native types supports Dart’s focus on clean and expressive syntax. By leveraging type inference, developers can reduce boilerplate and make FFI bindings easier to maintain and understand.

Kind

Style.

Bad Examples

import 'dart:ffi';

@Native<Pointer<Int32>>()
external Pointer<Int32> foo;

@Native<Void Function(Pointer)>()
external void bar(Pointer p);

Good Examples

import 'dart:ffi';

@Native()
external Pointer<Int32> foo;

@Native()
external void bar(Pointer p);

Considerations

  1. Backward Compatibility: Code explicitly declaring native types will remain valid but trigger the lint warning if the type can be inferred.
  2. Exceptions: If the native type cannot be inferred from the Dart signature, explicit annotation remains necessary.
  3. Tooling: IDEs should provide quick fixes to remove unnecessary native type specifications in @Native annotations.

/cc @bwilkerson
/cc @dcharkes

@halildurmus halildurmus added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label Dec 20, 2024
@dcharkes
Copy link
Contributor

We'll likely disable such lint for code generators (package FFIgen, package:win32), as branching on logic whether it can be omitted or not would complicate the code generators. It's the same kind of logic one will always add type params everywhere if they can be inferred half of the time. Otherwise you need to duplicate inference logic in the code generators.

I'd hope most FFI bindings are generated by code generators, so that makes such lint less important for the eco system.

But if people are writing bindings by hand, and we cannot reasonably code generate them, and they want cleaner bindings, yes let's add this lint. 👍

(Side note, did we think about automatic unwrapping of TypedData to Pointer and passing pointers to Arrays and structs in isLeaf?)

@halildurmus
Copy link
Contributor Author

halildurmus commented Dec 20, 2024

We'll likely disable such lint for code generators (package FFIgen, package:win32), as branching on logic whether it can be omitted or not would complicate the code generators. It's the same kind of logic one will always add type params everywhere if they can be inferred half of the time. Otherwise you need to duplicate inference logic in the code generators.

I agree. 👍

(Side note: Currently, package:win32 doesn’t use @Native for Win32 functions. I could modify the generator to use it, but this would require investigating which dynamic libraries (e.g., ole32.dll, kernel32.dll) are automatically loaded (accessible in DynamicLibrary.process()) in Windows processes to appropriately apply @Native. However, I don't think it's possible to convert other functions to use @Native, or maybe I'm missing something?)

I'd hope most FFI bindings are generated by code generators, so that makes such lint less important for the eco system.

I believe that’s probably the case.

But if people are writing bindings by hand, and we cannot reasonably code generate them, and they want cleaner bindings, yes let's add this lint. 👍

Although I don’t think many people are writing bindings by hand, I agree that this lint would still be valuable.

(Side note, did we think about automatic unwrapping of TypedData to Pointer and passing pointers to Arrays and structs in isLeaf?)

That would be a great feature! I believe this has been proposed in #54739 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion.
Projects
None yet
Development

No branches or pull requests

2 participants