mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:50:11 +00:00
[analyzer] Consider VarArgs in @Native
check
Methods and functions annotated with `@FfiNative` and `@Native` are validated to ensure their Dart signature matches the one from the annotation. For those functions, the lengths of the parameters is compared two times: In `_validateCompatibleFunctionTypes` and in `_checkFfiNative`, with the latter being responsible for emitting a more-specific error message. However, it fails to consider that a single `VarArg` reference in the native function type would get expanded to multiple formals in Dart. This fixes the problem by properly expanding variadic types in `_checkFfiNative` as well. Closes https://github.com/dart-lang/sdk/issues/53680 Bug: 53680 Change-Id: Ifb93eba8ac9f39697dc415dc337110109449e366 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/329360 Commit-Queue: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
a46ac84206
commit
1aa8232308
|
@ -338,7 +338,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
|
|||
FfiCode.FFI_NATIVE_MUST_BE_EXTERNAL, errorNode);
|
||||
}
|
||||
|
||||
var ffiParameterTypes = ffiSignature.normalParameterTypes;
|
||||
var ffiParameterTypes =
|
||||
ffiSignature.normalParameterTypes.flattenVarArgs();
|
||||
var ffiParameters = ffiSignature.parameters;
|
||||
|
||||
if ((declarationElement is MethodElement ||
|
||||
|
@ -346,11 +347,11 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
|
|||
!declarationElement.isStatic) {
|
||||
// Instance methods must have the receiver as an extra parameter in the
|
||||
// FfiNative annotation.
|
||||
if (formalParameters.length + 1 != ffiSignature.parameters.length) {
|
||||
if (formalParameters.length + 1 != ffiParameterTypes.length) {
|
||||
_errorReporter.reportErrorForNode(
|
||||
FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS_WITH_RECEIVER,
|
||||
errorNode,
|
||||
[formalParameters.length + 1, ffiSignature.parameters.length]);
|
||||
[formalParameters.length + 1, ffiParameterTypes.length]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -371,11 +372,11 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
|
|||
} else {
|
||||
// Number of parameters in the FfiNative annotation must match the
|
||||
// annotated declaration.
|
||||
if (formalParameters.length != ffiSignature.parameters.length) {
|
||||
if (formalParameters.length != ffiParameterTypes.length) {
|
||||
_errorReporter.reportErrorForNode(
|
||||
FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS,
|
||||
errorNode,
|
||||
[ffiSignature.parameters.length, formalParameters.length]);
|
||||
[ffiParameterTypes.length, formalParameters.length]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,6 +313,34 @@ external void doesntMatter(double x);
|
|||
]);
|
||||
}
|
||||
|
||||
test_NativeVarArgs() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
import 'dart:ffi';
|
||||
@Native<Int8 Function(Int64, VarArgs<(Int32, Double)>)>()
|
||||
external int doesntMatter(int x, int y, double z);
|
||||
''');
|
||||
}
|
||||
|
||||
test_NativeVarArgsTooFew() async {
|
||||
await assertErrorsInCode(r'''
|
||||
import 'dart:ffi';
|
||||
@Native<Int8 Function(Int64, VarArgs<(Int32, Double)>)>()
|
||||
external int doesntMatter(int x, int y);
|
||||
''', [
|
||||
error(FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS, 19, 98),
|
||||
]);
|
||||
}
|
||||
|
||||
test_NativeVarArgsTooMany() async {
|
||||
await assertErrorsInCode(r'''
|
||||
import 'dart:ffi';
|
||||
@Native<Int8 Function(Int64, VarArgs<(Int32, Double)>)>()
|
||||
external int doesntMatter(int x, int y, double z, int superfluous);
|
||||
''', [
|
||||
error(FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS, 19, 125),
|
||||
]);
|
||||
}
|
||||
|
||||
test_NativeVoidReturn() async {
|
||||
await assertErrorsInCode(r'''
|
||||
import 'dart:ffi';
|
||||
|
|
Loading…
Reference in a new issue