blob: e81f1a0ce5a3023240fd3cf3b36f55dedfb85f85 [file] [log] [blame]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/dart/error/ffi_code.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(LeafCallMustNotUseHandle);
});
}
@reflectiveTest
class LeafCallMustNotUseHandle extends PubPackageResolutionTest {
test_AsFunctionReturnsHandle() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
typedef NativeReturnsHandle = Handle Function();
typedef ReturnsHandle = Object Function();
doThings() {
Pointer<NativeFunction<NativeReturnsHandle>> p = Pointer.fromAddress(1337);
ReturnsHandle f = p.asFunction(isLeaf:true);
f();
}
''', [
error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 224, 10),
]);
}
test_AsFunctionTakesHandle() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
typedef NativeTakesHandle = Void Function(Handle);
typedef TakesHandle = void Function(Object);
class MyClass {}
doThings() {
Pointer<NativeFunction<NativeTakesHandle>> p = Pointer.fromAddress(1337);
TakesHandle f = p.asFunction(isLeaf:true);
f(MyClass());
}
''', [
error(FfiCode.LEAF_CALL_MUST_NOT_TAKE_HANDLE, 241, 10),
]);
}
test_class_getter() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
base class NativeFieldWrapperClass1 {}
base class A extends NativeFieldWrapperClass1 {
@Native<Handle Function(Pointer<Void>)>(symbol: 'foo', isLeaf:true)
external Object get foo;
}
''', [
error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 200, 3),
]);
}
test_LookupFunctionReturnsHandle() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
typedef NativeReturnsHandle = Handle Function();
typedef ReturnsHandle = Object Function();
doThings() {
DynamicLibrary l = DynamicLibrary.open("my_lib");
l.lookupFunction<NativeReturnsHandle, ReturnsHandle>("timesFour", isLeaf:true);
}
''', [
error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 195, 19),
]);
}
test_LookupFunctionTakesHandle() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
typedef NativeTakesHandle = Void Function(Handle);
typedef TakesHandle = void Function(Object);
class MyClass {}
doThings() {
DynamicLibrary l = DynamicLibrary.open("my_lib");
l.lookupFunction<NativeTakesHandle, TakesHandle>("timesFour", isLeaf:true);
}
''', [
error(FfiCode.LEAF_CALL_MUST_NOT_TAKE_HANDLE, 216, 17),
]);
}
test_unit_getter() async {
await assertErrorsInCode(r'''
import 'dart:ffi';
@Native<Handle Function()>(symbol: 'foo', isLeaf:true)
external Object get foo;
''', [
error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 95, 3),
]);
}
}