mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:55:08 +00:00
[analyzer/ffi] Fix Unwrap typed data error messages
Fixes issues reported by: TEST=pkg/analyzer/test/verify_diagnostics_test.dart * Fixes error messages on asFunction. * Fixes validation by introducing Uint8List to mock sdk. * Removes unused typed_data import in example snippet. * Fixes error locations in example snippets Bug: https://github.com/dart-lang/sdk/issues/44589 Change-Id: I82261eea5e55cbafa686865a92131a449a7642f5 Cq-Include-Trybots: luci.dart.try:pkg-linux-debug-try,pkg-linux-release-try,pkg-mac-release-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340921 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
d548c07996
commit
069e617ef4
|
@ -910,7 +910,7 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
|
|||
}
|
||||
_validateFfiTypedDataUnwrapping(
|
||||
F,
|
||||
T,
|
||||
TPrime,
|
||||
errorNode,
|
||||
isLeaf: isLeaf,
|
||||
isCall: true,
|
||||
|
@ -1086,6 +1086,11 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
|
|||
int i = 0;
|
||||
final nativeParamTypes = nativeType.normalParameterTypes.flattenVarArgs();
|
||||
for (final dartParam in dartType.normalParameterTypes) {
|
||||
if (i >= nativeParamTypes.length) {
|
||||
// Cascading error as not the same amount of arguments.
|
||||
// Already results in an error earlier.
|
||||
return;
|
||||
}
|
||||
final nativeParam = nativeParamTypes[i];
|
||||
i++;
|
||||
if (dartParam.isTypedData && nativeParam.isPointer) {
|
||||
|
|
|
@ -1378,6 +1378,10 @@ final MockSdkLibrary _LIB_TYPED_DATA = MockSdkLibrary(
|
|||
'''
|
||||
library dart.typed_data;
|
||||
|
||||
abstract final class Uint8List {
|
||||
external factory Uint8List(int length);
|
||||
}
|
||||
|
||||
abstract final class Int8List {
|
||||
external factory Int8List(int length);
|
||||
}
|
||||
|
|
|
@ -19859,7 +19859,7 @@ FfiCode:
|
|||
import 'dart:typed_data';
|
||||
|
||||
void f(Pointer<NativeFunction<Void Function(Pointer<Uint8>)>> p) {
|
||||
[!p.asFunction<void Function(Uint8List)>()!];
|
||||
p.asFunction<[!void Function(Uint8List)!]>();
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -19905,7 +19905,7 @@ FfiCode:
|
|||
import 'dart:typed_data';
|
||||
|
||||
void f(Pointer<NativeFunction<Pointer<Uint8> Function()>> p) {
|
||||
[!p.asFunction<Uint8List Function()>()!];
|
||||
p.asFunction<[!Uint8List Function()!]>();
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -19915,7 +19915,6 @@ FfiCode:
|
|||
|
||||
```dart
|
||||
import 'dart:ffi';
|
||||
import 'dart:typed_data';
|
||||
|
||||
void f(Pointer<NativeFunction<Pointer<Uint8> Function()>> p) {
|
||||
p.asFunction<Pointer<Uint8> Function()>();
|
||||
|
@ -19949,7 +19948,7 @@ FfiCode:
|
|||
void f(Uint8List i) {}
|
||||
|
||||
void g() {
|
||||
Pointer.fromFunction<Void Function(Pointer<Uint8>)>(f);
|
||||
Pointer.fromFunction<Void Function(Pointer<Uint8>)>([!f!]);
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -19959,7 +19958,6 @@ FfiCode:
|
|||
|
||||
```dart
|
||||
import 'dart:ffi';
|
||||
import 'dart:typed_data';
|
||||
|
||||
void f(Pointer<Uint8> i) {}
|
||||
|
||||
|
|
|
@ -1918,6 +1918,90 @@ extension [!mixin!] on int {}
|
|||
|
||||
Choose a different name for the declaration.
|
||||
|
||||
### callback_must_not_use_typed_data
|
||||
|
||||
_FFI callbacks can't take typed data arguments or return value._
|
||||
|
||||
#### Description
|
||||
|
||||
The analyzer produces this diagnostic when an invocation of
|
||||
`Pointer.fromFunction`, one of`NativeCallable`'s constructors has a
|
||||
typed data argument or return value."
|
||||
|
||||
Typed data unwrapping is only supported on arguments for leaf FFI calls.
|
||||
|
||||
For more information about FFI, see [C interop using dart:ffi][ffi].
|
||||
|
||||
#### Example
|
||||
|
||||
The following code produces this diagnostic because the parameter type
|
||||
of `g` is a typed data.
|
||||
|
||||
{% prettify dart tag=pre+code %}
|
||||
import 'dart:ffi';
|
||||
import 'dart:typed_data';
|
||||
|
||||
void f(Uint8List i) {}
|
||||
|
||||
void g() {
|
||||
Pointer.fromFunction<Void Function(Pointer<Uint8>)>([!f!]);
|
||||
}
|
||||
{% endprettify %}
|
||||
|
||||
#### Common fixes
|
||||
|
||||
Use the `Pointer` type instead:
|
||||
|
||||
{% prettify dart tag=pre+code %}
|
||||
import 'dart:ffi';
|
||||
|
||||
void f(Pointer<Uint8> i) {}
|
||||
|
||||
void g() {
|
||||
Pointer.fromFunction<Void Function(Pointer<Uint8>)>(f);
|
||||
}
|
||||
{% endprettify %}
|
||||
|
||||
### call_must_not_return_typed_data
|
||||
|
||||
_FFI calls can't return typed data._
|
||||
|
||||
#### Description
|
||||
|
||||
The analyzer produces this diagnostic when the return type of
|
||||
`Pointer.asFunction`, `DynamicLibrary.lookupFunction`, or
|
||||
`@Native` is a typed data.
|
||||
|
||||
Typed data unwrapping is only supported on arguments for leaf FFI calls.
|
||||
|
||||
For more information about FFI, see [C interop using dart:ffi][ffi].
|
||||
|
||||
#### Example
|
||||
|
||||
The following code produces this diagnostic because the dart function
|
||||
signature contains a typed data, but the `isLeaf` argument is `false`:
|
||||
|
||||
{% prettify dart tag=pre+code %}
|
||||
import 'dart:ffi';
|
||||
import 'dart:typed_data';
|
||||
|
||||
void f(Pointer<NativeFunction<Pointer<Uint8> Function()>> p) {
|
||||
p.asFunction<[!Uint8List Function()!]>();
|
||||
}
|
||||
{% endprettify %}
|
||||
|
||||
#### Common fixes
|
||||
|
||||
Use the `Pointer` type instead:
|
||||
|
||||
{% prettify dart tag=pre+code %}
|
||||
import 'dart:ffi';
|
||||
|
||||
void f(Pointer<NativeFunction<Pointer<Uint8> Function()>> p) {
|
||||
p.asFunction<Pointer<Uint8> Function()>();
|
||||
}
|
||||
{% endprettify %}
|
||||
|
||||
### case_block_not_terminated
|
||||
|
||||
_The last statement of the 'case' should be 'break', 'continue', 'rethrow',
|
||||
|
@ -15167,6 +15251,52 @@ class A {
|
|||
class B implements A {}
|
||||
{% endprettify %}
|
||||
|
||||
### non_leaf_call_must_not_take_typed_data
|
||||
|
||||
_FFI non-leaf calls can't take typed data arguments._
|
||||
|
||||
#### Description
|
||||
|
||||
The analyzer produces this diagnostic when the value of the `isLeaf`
|
||||
argument of `Pointer.asFunction`, `DynamicLibrary.lookupFunction`, or
|
||||
`@Native` is `false` and the Dart function signature contains a typed
|
||||
data parameter.
|
||||
|
||||
Typed data unwrapping is only supported on arguments for leaf FFI calls.
|
||||
|
||||
For more information about FFI, see [C interop using dart:ffi][ffi].
|
||||
|
||||
#### Example
|
||||
|
||||
The following code produces this diagnostic because the dart function
|
||||
signature contains a typed data, but the `isLeaf` argument is `false`:
|
||||
|
||||
{% prettify dart tag=pre+code %}
|
||||
import 'dart:ffi';
|
||||
import 'dart:typed_data';
|
||||
|
||||
void f(Pointer<NativeFunction<Void Function(Pointer<Uint8>)>> p) {
|
||||
p.asFunction<[!void Function(Uint8List)!]>();
|
||||
}
|
||||
{% endprettify %}
|
||||
|
||||
#### Common fixes
|
||||
|
||||
If the function has at least one typed data parameter, then add
|
||||
the `isLeaf` argument:
|
||||
|
||||
{% prettify dart tag=pre+code %}
|
||||
import 'dart:ffi';
|
||||
import 'dart:typed_data';
|
||||
|
||||
void f(Pointer<NativeFunction<Void Function(Pointer<Uint8>)>> p) {
|
||||
p.asFunction<void Function(Uint8List)>(isLeaf: true);
|
||||
}
|
||||
{% endprettify %}
|
||||
|
||||
If the function also uses `Handle`s, then it must be non-leaf. In That
|
||||
case use `Pointer`s instead of typed data.
|
||||
|
||||
### non_native_function_type_argument_to_pointer
|
||||
|
||||
_Can't invoke 'asFunction' because the function signature '{0}' for the pointer
|
||||
|
|
|
@ -90,4 +90,12 @@ void g2() {
|
|||
// [analyzer] COMPILE_TIME_ERROR.CALLBACK_MUST_NOT_USE_TYPED_DATA
|
||||
}
|
||||
|
||||
void foo1(Pointer<NativeFunction<Pointer<Uint8> Function()>> p) {
|
||||
p.asFunction<Uint8List Function()>(isLeaf: true);
|
||||
//^
|
||||
// [cfe] FFI calls can't return typed data.
|
||||
// ^^^^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CALL_MUST_NOT_RETURN_TYPED_DATA
|
||||
}
|
||||
|
||||
// TODO(https://dartbug.com/54181): Write negative tests for @Natives.
|
||||
|
|
Loading…
Reference in a new issue