dart-sdk/tests/ffi_2/vmspecific_static_checks_test.dart
Liam Appelbe f4eb5392e5 Refactor vmspecific_static_checks_test
Bug: https://github.com/dart-lang/sdk/issues/52754
Change-Id: I13d729f0caf61fa0ef261ffd1c382177a4115d8f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312342
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
2023-07-10 00:07:28 +00:00

1315 lines
47 KiB
Dart

// Copyright (c) 2019, 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.
//
// Dart test program for testing dart:ffi extra checks
//
// SharedObjects=ffi_test_dynamic_library ffi_test_functions
// @dart = 2.9
import 'dart:ffi';
import "package:ffi/ffi.dart";
import 'dylib_utils.dart';
void main() {
testGetGeneric();
testGetGeneric2();
testGetVoid();
testGetNativeFunction();
testGetNativeType();
testGetTypeMismatch();
testSetGeneric();
testSetGeneric2();
testSetVoid();
testSetNativeFunction();
testSetNativeType();
testSetTypeMismatch();
testAsFunctionGeneric();
testAsFunctionGeneric2();
testAsFunctionWrongNativeFunctionSignature();
testAsFunctionTypeMismatch();
testFromFunctionGeneric();
testFromFunctionGeneric2();
testFromFunctionWrongNativeFunctionSignature();
testFromFunctionTypeMismatch();
testFromFunctionClosure();
testFromFunctionTearOff();
testFromFunctionAbstract();
testFromFunctionFunctionExceptionValueMustBeConst();
testLookupFunctionGeneric();
testLookupFunctionGeneric2();
testLookupFunctionWrongNativeFunctionSignature();
testLookupFunctionTypeMismatch();
testLookupFunctionPointervoid();
testLookupFunctionPointerNFdyn();
testHandleVariance();
testEmptyStructLookupFunctionArgument();
testEmptyStructLookupFunctionReturn();
testEmptyStructAsFunctionArgument();
testEmptyStructAsFunctionReturn();
testEmptyStructFromFunctionArgument();
testEmptyStructFromFunctionReturn();
testAllocateGeneric();
testAllocateNativeType();
testRefStruct();
testSizeOfGeneric();
testSizeOfNativeType();
testSizeOfHandle();
testElementAtGeneric();
testElementAtNativeType();
testLookupFunctionIsLeafMustBeConst();
testAsFunctionIsLeafMustBeConst();
testLookupFunctionTakesHandle();
testAsFunctionTakesHandle();
testLookupFunctionReturnsHandle();
testAsFunctionReturnsHandle();
}
typedef Int8UnOp = Int8 Function(Int8);
typedef IntUnOp = int Function(int);
void testGetGeneric() {
int generic(Pointer p) {
int result;
result = p.value;
// ^^^^^
// [cfe] The getter 'value' isn't defined for the class 'Pointer<NativeType>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
return result;
}
Pointer<Int8> p = calloc();
p.value = 123;
Pointer loseType = p;
generic(loseType);
calloc.free(p);
}
void testGetGeneric2() {
T generic<T extends Object>() {
Pointer<Int8> p = calloc();
p.value = 123;
T result;
result = p.value;
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
// ^
// [cfe] A value of type 'int' can't be assigned to a variable of type 'T'.
calloc.free(p);
return result;
}
generic<int>();
}
void testGetVoid() {
Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
p2.value;
// ^^^^^
// [cfe] The getter 'value' isn't defined for the class 'Pointer<Void>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
calloc.free(p1);
}
void testGetNativeFunction() {
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
IntUnOp f = p.value;
// ^^^^^
// [cfe] The getter 'value' isn't defined for the class 'Pointer<NativeFunction<Int8 Function(Int8)>>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
}
void testGetNativeType() {
// Is it possible to obtain a Pointer<NativeType> at all?
}
void testGetTypeMismatch() {
Pointer<Pointer<Int16>> p = calloc();
Pointer<Int16> typedNull = nullptr;
p.value = typedNull;
// this fails to compile due to type mismatch
Pointer<Int8> p2 = p.value;
// ^
// [cfe] A value of type 'Pointer<Int16>' can't be assigned to a variable of type 'Pointer<Int8>'.
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
calloc.free(p);
}
void testSetGeneric() {
void generic(Pointer p) {
p.value = 123;
//^^^^^
// [cfe] The setter 'value' isn't defined for the class 'Pointer<NativeType>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_SETTER
}
Pointer<Int8> p = calloc();
p.value = 123;
Pointer loseType = p;
generic(loseType);
calloc.free(p);
}
void testSetGeneric2() {
void generic<T extends Object>(T arg) {
Pointer<Int8> p = calloc();
p.value = arg;
// ^^^
// [cfe] A value of type 'T' can't be assigned to a variable of type 'int'.
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
calloc.free(p);
}
generic<int>(123);
}
void testSetVoid() {
Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
p2.value = 1234;
// ^^^^^
// [cfe] The setter 'value' isn't defined for the class 'Pointer<Void>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_SETTER
calloc.free(p1);
}
void testSetNativeFunction() {
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
IntUnOp f = (a) => a + 1;
p.value = f;
//^^^^^
// [cfe] The setter 'value' isn't defined for the class 'Pointer<NativeFunction<Int8 Function(Int8)>>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_SETTER
}
void testSetNativeType() {
// Is it possible to obtain a Pointer<NativeType> at all?
}
void testSetTypeMismatch() {
// the pointer to pointer types must match up
Pointer<Int8> pHelper = calloc();
pHelper.value = 123;
Pointer<Pointer<Int16>> p = calloc();
// this fails to compile due to type mismatch
p.value = pHelper;
// ^^^^^^^
// [cfe] A value of type 'Pointer<Int8>' can't be assigned to a variable of type 'Pointer<Int16>'.
// [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
calloc.free(pHelper);
calloc.free(p);
}
void testAsFunctionGeneric() {
T generic<T extends Function>() {
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
Function f;
f = p.asFunction<T>();
// ^
// [cfe] Expected type 'T' to be 'int Function(int)', which is the Dart type corresponding to 'NativeFunction<Int8 Function(Int8)>'.
// ^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
return f;
}
generic<IntUnOp>();
}
void testAsFunctionGeneric2() {
generic(Pointer<NativeFunction> p) {
Function f;
f = p.asFunction<IntUnOp>();
// ^
// [cfe] Expected type 'NativeFunction<Function>' to be a valid and instantiated subtype of 'NativeType'.
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER
return f;
}
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
generic(p);
}
void testAsFunctionWrongNativeFunctionSignature() {
Pointer<NativeFunction<IntUnOp>> p;
Function f = p.asFunction<IntUnOp>();
// ^
// [cfe] Expected type 'NativeFunction<int Function(int)>' to be a valid and instantiated subtype of 'NativeType'.
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER
}
typedef IntBinOp = int Function(int, int);
void testAsFunctionTypeMismatch() {
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
IntBinOp f = p.asFunction();
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'int Function(int, int)' to be 'int Function(int)', which is the Dart type corresponding to 'NativeFunction<Int8 Function(Int8)>'.
}
typedef NativeDoubleUnOp = Double Function(Double);
typedef DoubleUnOp = double Function(double);
double myTimesThree(double d) => d * 3;
int myTimesFour(int i) => i * 4;
void testFromFunctionGeneric() {
Pointer<NativeFunction> generic<T extends Function>(T f) {
Pointer<NativeFunction<NativeDoubleUnOp>> result;
result = Pointer.fromFunction(f);
// ^
// [cfe] fromFunction expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context.
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
return result;
}
generic(myTimesThree);
}
void testFromFunctionGeneric2() {
Pointer<NativeFunction<T>> generic<T extends Function>() {
Pointer<NativeFunction<T>> result;
result = Pointer.fromFunction(myTimesThree);
// ^^^^^^^^^^^^
// [cfe] Expected type 'NativeFunction<T>' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
return result;
}
generic<NativeDoubleUnOp>();
}
void testFromFunctionWrongNativeFunctionSignature() {
Pointer.fromFunction<IntUnOp>(myTimesFour);
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
// ^
// [cfe] Expected type 'NativeFunction<int Function(int)>' to be a valid and instantiated subtype of 'NativeType'.
}
void testFromFunctionTypeMismatch() {
Pointer<NativeFunction<NativeDoubleUnOp>> p;
p = Pointer.fromFunction(myTimesFour);
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'int Function(int)' to be 'double Function(double)', which is the Dart type corresponding to 'NativeFunction<Double Function(Double)>'.
}
void testFromFunctionClosure() {
DoubleUnOp someClosure = (double z) => z / 27.0;
Pointer<NativeFunction<NativeDoubleUnOp>> p;
p = Pointer.fromFunction(someClosure);
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISSING_EXCEPTION_VALUE
// ^
// [cfe] fromFunction expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context.
}
class X {
double tearoff(double d) => d / 27.0;
}
void testFromFunctionTearOff() {
DoubleUnOp fld = X().tearoff;
Pointer<NativeFunction<NativeDoubleUnOp>> p;
p = Pointer.fromFunction(fld);
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISSING_EXCEPTION_VALUE
// ^
// [cfe] fromFunction expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context.
}
void testFromFunctionAbstract() {
Pointer.fromFunction<Function>(testFromFunctionAbstract);
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
// ^
// [cfe] Expected type 'NativeFunction<Function>' to be a valid and instantiated subtype of 'NativeType'.
}
void testFromFunctionFunctionExceptionValueMustBeConst() {
final notAConst = 1.1;
Pointer<NativeFunction<NativeDoubleUnOp>> p;
p = Pointer.fromFunction(myTimesThree, notAConst);
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_MUST_BE_A_CONSTANT
// ^
// [cfe] Exceptional return value must be a constant.
}
void testLookupFunctionGeneric() {
Function generic<T extends Function>() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Function result;
result = l.lookupFunction<T, DoubleUnOp>("cos");
// ^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
// ^
// [cfe] Expected type 'NativeFunction<T>' to be a valid and instantiated subtype of 'NativeType'.
return result;
}
generic<NativeDoubleUnOp>();
}
void testLookupFunctionGeneric2() {
Function generic<T extends Function>() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Function result;
result = l.lookupFunction<NativeDoubleUnOp, T>("cos");
// ^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'T' to be 'double Function(double)', which is the Dart type corresponding to 'NativeFunction<Double Function(Double)>'.
return result;
}
generic<DoubleUnOp>();
}
void testLookupFunctionWrongNativeFunctionSignature() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
l.lookupFunction<IntUnOp, IntUnOp>("cos");
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
//^
// [cfe] Expected type 'NativeFunction<int Function(int)>' to be a valid and instantiated subtype of 'NativeType'.
}
void testLookupFunctionTypeMismatch() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
l.lookupFunction<NativeDoubleUnOp, IntUnOp>("cos");
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
//^
// [cfe] Expected type 'int Function(int)' to be 'double Function(double)', which is the Dart type corresponding to 'NativeFunction<Double Function(Double)>'.
}
typedef PointervoidN = Void Function(Pointer<void>);
typedef PointervoidD = void Function(Pointer<void>);
void testLookupFunctionPointervoid() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
// TODO(https://dartbug.com/44593): This should be a compile-time error in CFE.
// l.lookupFunction<PointervoidN, PointervoidD>("cos");
}
typedef PointerNFdynN = Void Function(Pointer<NativeFunction>);
typedef PointerNFdynD = void Function(Pointer<NativeFunction>);
void testLookupFunctionPointerNFdyn() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
// TODO(https://dartbug.com/44594): Should this be an error or not?
// l.lookupFunction<PointerNFdynN, PointerNFdynD>("cos");
}
// error on missing field annotation
class TestStruct extends Struct {
@Double()
double x;
/**/ double y;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISSING_ANNOTATION_ON_STRUCT_FIELD
// ^
// [cfe] Field 'y' requires exactly one annotation to declare its native type, which cannot be Void. dart:ffi Structs and Unions cannot have regular Dart fields.
}
// Cannot extend structs.
class TestStruct3 extends TestStruct {}
// ^^^^^^^^^^^
// [cfe] Class 'TestStruct' cannot be extended or implemented.
// [cfe] TestStruct 'TestStruct3' is empty. Empty structs and unions are undefined behavior.
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_STRUCT_CLASS
// error on double annotation
class TestStruct4 extends Struct {
@Double()
/**/ @Double()
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTRA_ANNOTATION_ON_STRUCT_FIELD
double z;
// ^
// [cfe] Field 'z' requires exactly one annotation to declare its native type, which cannot be Void. dart:ffi Structs and Unions cannot have regular Dart fields.
}
// error on annotation not matching up
class TestStruct5 extends Struct {
/**/ @Int64()
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISMATCHED_ANNOTATION_ON_STRUCT_FIELD
double z;
// ^
// [cfe] Expected type 'double' to be 'int', which is the Dart type corresponding to 'Int64'.
Pointer notEmpty;
}
// error on annotation not matching up
class TestStruct6 extends Struct {
/**/ @Void()
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISMATCHED_ANNOTATION_ON_STRUCT_FIELD
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_ANNOTATION_CONSTRUCTOR
// ^
// [cfe] The class 'Void' is abstract and can't be instantiated.
double z;
// ^
// [cfe] Field 'z' requires exactly one annotation to declare its native type, which cannot be Void. dart:ffi Structs and Unions cannot have regular Dart fields.
Pointer notEmpty;
}
// error on annotation not matching up
class TestStruct7 extends Struct {
/**/ @NativeType()
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISMATCHED_ANNOTATION_ON_STRUCT_FIELD
// ^
// [cfe] The class 'NativeType' is abstract and can't be instantiated.
double z;
// ^
// [cfe] Field 'z' requires exactly one annotation to declare its native type, which cannot be Void. dart:ffi Structs and Unions cannot have regular Dart fields.
Pointer notEmpty;
}
// error on field initializer on field
class TestStruct8 extends Struct {
@Double()
double z = 10.0;
// ^
// [cfe] Field 'z' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution.
// [analyzer] COMPILE_TIME_ERROR.FIELD_IN_STRUCT_WITH_INITIALIZER
Pointer notEmpty;
}
// error on field initializer in constructor
class TestStruct9 extends Struct {
@Double()
double z;
// ^
// [cfe] Field 'z' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution.
Pointer notEmpty;
TestStruct9() : z = 0.0 {}
// ^
// [cfe] Field 'z' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution.
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_IN_STRUCT
}
// Struct classes may not be generic.
class TestStruct11<T> extends Struct<TestStruct11<dynamic>> {}
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
// [analyzer] COMPILE_TIME_ERROR.GENERIC_STRUCT_SUBCLASS
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [cfe] Expected 0 type arguments.
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_TYPE_ARGUMENTS
// Structs may not appear inside structs (currently, there is no suitable
// annotation).
class TestStruct12 extends Struct {
/**/ @Pointer
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_ANNOTATION
// ^
// [cfe] This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor.
TestStruct9 struct;
Pointer notEmpty;
}
class DummyAnnotation {
const DummyAnnotation();
}
// Structs fields may have other annotations.
class TestStruct13 extends Struct {
@DummyAnnotation()
@Double()
double z;
}
// Cannot extend native types.
class ENativeType extends NativeType {}
// ^^^^^^^^^^
// [cfe] The class 'NativeType' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EInt8 extends Int8 {}
// ^^^^
// [cfe] The class 'Int8' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EInt16 extends Int16 {}
// ^^^^^
// [cfe] The class 'Int16' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EInt32 extends Int32 {}
// ^^^^^
// [cfe] The class 'Int32' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EInt64 extends Int64 {}
// ^^^^^
// [cfe] The class 'Int64' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EUint8 extends Uint8 {}
// ^^^^^
// [cfe] The class 'Uint8' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EUint16 extends Uint16 {}
// ^^^^^^
// [cfe] The class 'Uint16' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EUint32 extends Uint32 {}
// ^^^^^^
// [cfe] The class 'Uint32' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EUint64 extends Uint64 {}
// ^^^^^^
// [cfe] The class 'Uint64' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EIntPtr extends IntPtr {}
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [cfe] The class 'IntPtr' can't be extended outside of its library because it's a final class.
// ^
// [cfe] Class 'IntPtr' cannot be extended or implemented.
// [cfe] Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a NativeType integer with a fixed size.
// [cfe] Classes extending 'AbiSpecificInteger' must have exactly one const constructor, no other members, and no type arguments.
class EFloat extends Float {}
// ^^^^^
// [cfe] The class 'Float' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EDouble extends Double {}
// ^^^^^^
// [cfe] The class 'Double' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EVoid extends Void {}
// ^^^^
// [cfe] The class 'Void' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class ENativeFunction extends NativeFunction {}
// ^^^^^^^^^^^^^^
// [cfe] The class 'NativeFunction' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class EPointer extends Pointer {}
// ^^^^^^^
// [cfe] The class 'Pointer' can't be extended outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS
// ^
// [cfe] The superclass, 'Pointer', has no unnamed constructor that takes no arguments.
// Cannot implement native natives or Struct.
// Cannot extend native types.
class INativeType implements NativeType {}
// ^^^^^^^^^^
// [cfe] The class 'NativeType' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IInt8 implements Int8 {}
// ^^^^
// [cfe] The class 'Int8' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IInt16 implements Int16 {}
// ^^^^^
// [cfe] The class 'Int16' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IInt32 implements Int32 {}
// ^^^^^
// [cfe] The class 'Int32' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IInt64 implements Int64 {}
// ^^^^^
// [cfe] The class 'Int64' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IUint8 implements Uint8 {}
// ^^^^^
// [cfe] The class 'Uint8' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IUint16 implements Uint16 {}
// ^^^^^^
// [cfe] The class 'Uint16' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IUint32 implements Uint32 {}
// ^^^^^^
// [cfe] The class 'Uint32' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IUint64 implements Uint64 {}
// ^^^^^^
// [cfe] The class 'Uint64' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IIntPtr implements IntPtr {}
// ^^^^^^
// [cfe] The class 'IntPtr' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_STRUCT_CLASS
// ^
// [cfe] Class 'Object' cannot be extended or implemented.
class IFloat implements Float {}
// ^^^^^
// [cfe] The class 'Float' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IDouble implements Double {}
// ^^^^^^
// [cfe] The class 'Double' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IVoid implements Void {}
// ^^^^
// [cfe] The class 'Void' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class INativeFunction implements NativeFunction {}
// ^^^^^^^^^^^^^^
// [cfe] The class 'NativeFunction' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IPointer implements Pointer {}
// ^^^^^^^^
// [cfe] The non-abstract class 'IPointer' is missing implementations for these members:
// [analyzer] COMPILE_TIME_ERROR.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER
// ^^^^^^^
// [cfe] The class 'Pointer' can't be implemented outside of its library because it's a final class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IStruct implements Struct {}
// ^^^^^^^
// [cfe] Class 'Object' cannot be extended or implemented.
// ^^^^^^
// [cfe] The class 'Struct' can't be implemented outside of its library because it's a base class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class IOpaque implements Opaque {}
// ^^^^^^^
// [cfe] Class 'Object' cannot be extended or implemented.
// ^^^^^^
// [cfe] The class 'Opaque' can't be implemented outside of its library because it's a base class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
class MyClass {
int x;
MyClass(this.x);
}
final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
void testHandleVariance() {
// Taking a more specific argument is okay.
testLibrary.lookupFunction<Handle Function(Handle), Object Function(MyClass)>(
"PassObjectToC");
// Requiring a more specific return type is not, this requires a cast from
// the user.
testLibrary.lookupFunction<Handle Function(Handle), MyClass Function(Object)>(
// ^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'MyClass Function(Object)' to be 'Object Function(Object)', which is the Dart type corresponding to 'NativeFunction<Handle Function(Handle)>'.
"PassObjectToC");
}
class TestStruct1001 extends Struct {
/**/ Handle handle;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_FIELD_TYPE_IN_STRUCT
// ^
// [cfe] Field 'handle' requires exactly one annotation to declare its native type, which cannot be Void. dart:ffi Structs and Unions cannot have regular Dart fields.
Pointer notEmpty;
}
class TestStruct1002 extends Struct {
/**/ @Handle()
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_ANNOTATION_CONSTRUCTOR
// ^
// [cfe] The class 'Handle' is abstract and can't be instantiated.
/**/ Object handle;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_FIELD_TYPE_IN_STRUCT
// ^
// [cfe] Field 'handle' requires exactly one annotation to declare its native type, which cannot be Void. dart:ffi Structs and Unions cannot have regular Dart fields.
Pointer notEmpty;
}
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] Struct 'EmptyStruct' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] 'EmptyStruct' is already declared in this scope.
// [cfe] Struct 'EmptyStruct#1#0' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
void testEmptyStructLookupFunctionArgument() {
testLibrary.lookupFunction<
// ^
// [cfe] Expected type 'NativeFunction<Void Function(invalid-type)>' to be a valid and instantiated subtype of 'NativeType'.
/**/ Void Function(EmptyStruct),
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
// ^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
void Function(EmptyStruct)>("DoesNotExist");
// ^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
}
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] 'EmptyStruct' is already declared in this scope.
// [cfe] Struct 'EmptyStruct#2#0' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
void testEmptyStructLookupFunctionReturn() {
testLibrary.lookupFunction<EmptyStruct Function(), EmptyStruct Function()>(
// ^^^^^^^^^^^^^^^^^^^^^^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
// ^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
// ^
// [cfe] Expected type 'NativeFunction<invalid-type Function()>' to be a valid and instantiated subtype of 'NativeType'.
"DoesNotExist");
}
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] 'EmptyStruct' is already declared in this scope.
// [cfe] Struct 'EmptyStruct#3#0' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
void testEmptyStructAsFunctionArgument() {
final Pointer<NativeFunction<Void Function(EmptyStruct)>> pointer =
// ^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
Pointer.fromAddress(1234);
pointer.asFunction<void Function(EmptyStruct)>();
// ^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
// ^
// [cfe] Expected type 'NativeFunction<Void Function(invalid-type)>' to be a valid and instantiated subtype of 'NativeType'.
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER
}
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] 'EmptyStruct' is already declared in this scope.
// [cfe] Struct 'EmptyStruct#4#0' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
void testEmptyStructAsFunctionReturn() {
final Pointer<NativeFunction<EmptyStruct Function()>> pointer =
// ^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
Pointer.fromAddress(1234);
pointer.asFunction<EmptyStruct Function()>();
// ^^^^^^^^^^^^^^^^^^^^^^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
// [analyzer] COMPILE_TIME_ERROR.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER
// ^
// [cfe] Expected type 'NativeFunction<invalid-type Function()>' to be a valid and instantiated subtype of 'NativeType'.
}
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] 'EmptyStruct' is already declared in this scope.
// [cfe] Struct 'EmptyStruct#5#0' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
void _consumeEmptyStruct(EmptyStruct e) => print(e);
// ^
// [cfe] 'EmptyStruct' isn't a type.
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
void testEmptyStructFromFunctionArgument() {
Pointer.fromFunction<Void Function(EmptyStruct)>(_consumeEmptyStruct);
// ^
// [cfe] Expected type 'NativeFunction<Void Function(invalid-type)>' to be a valid and instantiated subtype of 'NativeType'.
// ^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
}
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] 'EmptyStruct' is already declared in this scope.
// [cfe] Struct 'EmptyStruct#6#0' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
/**/ EmptyStruct _returnEmptyStruct() => EmptyStruct();
// ^^^^^^^^^^^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
// [analyzer] COMPILE_TIME_ERROR.CREATION_OF_STRUCT_OR_UNION
// ^
// [cfe] 'EmptyStruct' isn't a type.
void testEmptyStructFromFunctionReturn() {
Pointer.fromFunction<EmptyStruct Function()>(_returnEmptyStruct);
// ^^^^^^^^^^^^^^^^^^^^^^
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
// ^
// [cfe] Expected type 'NativeFunction<invalid-type Function()>' to be a valid and instantiated subtype of 'NativeType'.
}
class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] 'EmptyStruct' is already declared in this scope.
// [cfe] Struct 'EmptyStruct#7#0' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
class HasNestedEmptyStruct extends Struct {
EmptyStruct nestedEmptyStruct;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
// ^
// [cfe] Field 'nestedEmptyStruct' requires exactly one annotation to declare its native type, which cannot be Void. dart:ffi Structs and Unions cannot have regular Dart fields.
//^
// [cfe] 'EmptyStruct' isn't a type.
// [cfe] Can't use 'EmptyStruct' because it is declared more than once.
Pointer notEmpty;
}
void testAllocateGeneric() {
Pointer<T> generic<T extends NativeType>() {
Pointer<T> pointer = nullptr;
pointer = calloc();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'T' to be a valid and instantiated subtype of 'NativeType'.
return pointer;
}
Pointer p = generic<Int64>();
}
void testAllocateNativeType() {
/**/ calloc();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'NativeType' to be a valid and instantiated subtype of 'NativeType'.
}
void testRefStruct() {
final myStructPointer = calloc<TestStruct13>();
Pointer<Struct> structPointer = myStructPointer;
/**/ structPointer.ref;
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'Struct' to be a valid and instantiated subtype of 'NativeType'.
calloc.free(myStructPointer);
}
T genericRef<T extends Struct>(Pointer<T> p) => p.ref;
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'T' to be a valid and instantiated subtype of 'NativeType'.
T genericRef2<T extends Struct>(Pointer<T> p) => p.cast<T>().ref;
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'T' to be a valid and instantiated subtype of 'NativeType'.
T genericRef3<T extends Struct>(Pointer<T> p) => p[0];
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'T' to be a valid and instantiated subtype of 'NativeType'.
T genericRef4<T extends Struct>(Array<T> p) => p[0];
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'T' to be a valid and instantiated subtype of 'NativeType'.
void testSizeOfGeneric() {
int generic<T extends Pointer>() {
int size = sizeOf<IntPtr>();
size = sizeOf<T>();
// ^^^^^^^^^^^
// [cfe] Expected type 'T' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
return size;
}
int size = generic<Pointer<Int64>>();
}
void testSizeOfNativeType() {
sizeOf();
//^^^^^^^^
// [cfe] Expected type 'NativeType' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
}
void testSizeOfHandle() {
sizeOf<Handle>();
//^^^^^^^^^^^^^^^^
// [cfe] Expected type 'Handle' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
}
void testElementAtGeneric() {
Pointer<T> generic<T extends NativeType>(Pointer<T> pointer) {
Pointer<T> returnValue = pointer;
returnValue = returnValue.elementAt(1);
// ^^^^^^^^^
// [cfe] The method 'elementAt' isn't defined for the class 'Pointer<T>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
return returnValue;
}
Pointer<Int8> p = calloc();
p.elementAt(1);
generic(p);
calloc.free(p);
}
void testElementAtNativeType() {
Pointer<Int8> p = calloc();
p.elementAt(1);
Pointer<NativeType> p2 = p;
p2.elementAt(1);
// ^^^^^^^^^
// [cfe] The method 'elementAt' isn't defined for the class 'Pointer<NativeType>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
calloc.free(p);
}
class TestStruct1400 extends Struct {
@Array(8)
@Array(8)
//^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTRA_SIZE_ANNOTATION_CARRAY
Array<Uint8> a0;
// ^
// [cfe] Field 'a0' must have exactly one 'Array' annotation.
}
class TestStruct1401 extends Struct {
/**/ Array<Uint8> a0;
// ^
// [cfe] Field 'a0' must have exactly one 'Array' annotation.
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISSING_SIZE_ANNOTATION_CARRAY
Pointer<Uint8> notEmpty;
}
class TestStruct1402 extends Struct {
/**/ @Array(8, 8, 8)
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
Array<Array<Uint8>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
Pointer<Uint8> notEmpty;
}
class TestStruct1403 extends Struct {
/**/ @Array(8, 8)
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
Array<Array<Array<Uint8>>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
Pointer<Uint8> notEmpty;
}
class TestStruct1404 extends Struct {
/**/ @Array.multi([8, 8, 8])
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
Array<Array<Uint8>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
Pointer<Uint8> notEmpty;
}
class TestStruct1405 extends Struct {
/**/ @Array.multi([8, 8])
// ^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
Array<Array<Array<Uint8>>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
Pointer<Uint8> notEmpty;
}
void testLookupFunctionIsLeafMustBeConst() {
bool notAConst = false;
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
/**/ l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour",
// ^
// [cfe] Argument 'isLeaf' must be a constant.
isLeaf: notAConst);
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_MUST_BE_A_CONSTANT
}
void testAsFunctionIsLeafMustBeConst() {
bool notAConst = false;
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
IntUnOp f = p.asFunction(isLeaf: notAConst);
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_MUST_BE_A_CONSTANT
// ^
// [cfe] Argument 'isLeaf' must be a constant.
}
typedef NativeTakesHandle = Void Function(Handle);
typedef TakesHandle = void Function(Object);
void testLookupFunctionTakesHandle() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
l.lookupFunction<NativeTakesHandle, TakesHandle>("takesHandle", isLeaf: true);
// ^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.LEAF_CALL_MUST_NOT_TAKE_HANDLE
//^
// [cfe] FFI leaf call must not have Handle argument types.
}
void testAsFunctionTakesHandle() {
Pointer<NativeFunction<NativeTakesHandle>> p = Pointer.fromAddress(1337);
TakesHandle f = p.asFunction(isLeaf: true);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.LEAF_CALL_MUST_NOT_TAKE_HANDLE
// ^
// [cfe] FFI leaf call must not have Handle argument types.
}
typedef NativeReturnsHandle = Handle Function();
typedef ReturnsHandle = Object Function();
void testLookupFunctionReturnsHandle() {
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
/**/ l.lookupFunction<NativeReturnsHandle, ReturnsHandle>("returnsHandle",
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.LEAF_CALL_MUST_NOT_RETURN_HANDLE
// ^
// [cfe] FFI leaf call must not have Handle return type.
isLeaf: true);
}
void testAsFunctionReturnsHandle() {
Pointer<NativeFunction<NativeReturnsHandle>> p = Pointer.fromAddress(1337);
ReturnsHandle f = p.asFunction(isLeaf: true);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.LEAF_CALL_MUST_NOT_RETURN_HANDLE
// ^
// [cfe] FFI leaf call must not have Handle return type.
}
@Packed(1)
class TestStruct1600 extends Struct {
Pointer<Uint8> notEmpty;
}
@Packed(1)
/**/ @Packed(1)
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.PACKED_ANNOTATION
class TestStruct1601 extends Struct {
// ^
// [cfe] Struct 'TestStruct1601' must have at most one 'Packed' annotation.
Pointer<Uint8> notEmpty;
}
@Packed(3)
// ^
// [analyzer] COMPILE_TIME_ERROR.PACKED_ANNOTATION_ALIGNMENT
class TestStruct1602 extends Struct {
// ^
// [cfe] Only packing to 1, 2, 4, 8, and 16 bytes is supported.
Pointer<Uint8> notEmpty;
}
@Packed(0)
// ^
// [analyzer] COMPILE_TIME_ERROR.PACKED_ANNOTATION_ALIGNMENT
class TestStruct1607 extends Struct {
// ^
// [cfe] Only packing to 1, 2, 4, 8, and 16 bytes is supported.
Pointer<Uint8> notEmpty;
}
class TestStruct1800 extends Struct {
Pointer<Uint8> notEmpty;
@Array(-1)
// ^^
// [analyzer] COMPILE_TIME_ERROR.NON_POSITIVE_ARRAY_DIMENSION
Array<Uint8> inlineArray;
// ^
// [cfe] Array dimensions must be positive numbers.
}
class TestStruct1801 extends Struct {
Pointer<Uint8> notEmpty;
/**/ @Array(1, -1)
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
// ^^
// [analyzer] COMPILE_TIME_ERROR.NON_POSITIVE_ARRAY_DIMENSION
Array<Uint8> inlineArray;
// ^
// [cfe] Array dimensions must be positive numbers.
// [cfe] Field 'inlineArray' must have an 'Array' annotation that matches the dimensions.
}
class TestStruct1802 extends Struct {
Pointer<Uint8> notEmpty;
/**/ @Array.multi([2, 2, 2, 2, 2, 2, -1])
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
// ^^
// [analyzer] COMPILE_TIME_ERROR.NON_POSITIVE_ARRAY_DIMENSION
Array<Uint8> inlineArray;
// ^
// [cfe] Array dimensions must be positive numbers.
// [cfe] Field 'inlineArray' must have an 'Array' annotation that matches the dimensions.
}
@AbiSpecificIntegerMapping({
Abi.androidArm: Uint32(),
Abi.androidArm64: IntPtr(),
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED
Abi.androidIA32: AbiSpecificInteger1(),
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED
})
/**/ @AbiSpecificIntegerMapping({})
// ^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ABI_SPECIFIC_INTEGER_MAPPING_EXTRA
class AbiSpecificInteger1 extends AbiSpecificInteger {
// ^^^^^^^^^^^^^^^^^^^
// [cfe] Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a NativeType integer with a fixed size.
// [cfe] Classes extending 'AbiSpecificInteger' must have exactly one const constructor, no other members, and no type arguments.
// [analyzer] COMPILE_TIME_ERROR.ABI_SPECIFIC_INTEGER_INVALID
const AbiSpecificInteger1();
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
// [cfe] Constructor is marked 'const' so all fields must be final.
int get a => 4;
int b;
}
class AbiSpecificInteger2 implements AbiSpecificInteger {
// ^^^^^^^^^^^^^^^^^^^
// [cfe] Class 'Object' cannot be extended or implemented.
// ^^^^^^^^^^^^^^^^^^
// [cfe] The class 'AbiSpecificInteger' can't be implemented outside of its library because it's a base class.
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
const AbiSpecificInteger2();
}
class AbiSpecificInteger3 extends AbiSpecificInteger1 {
// ^^^^^^^^^^^^^^^^^^^
// [cfe] Class 'AbiSpecificInteger1' cannot be extended or implemented.
// [cfe] Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a NativeType integer with a fixed size.
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_STRUCT_CLASS
const AbiSpecificInteger3();
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
}
class AbiSpecificInteger4 implements AbiSpecificInteger1 {
// ^^^^^^^^^^^^^^^^^^^
// [cfe] Class 'Object' cannot be extended or implemented.
// [cfe] The non-abstract class 'AbiSpecificInteger4' is missing implementations for these members:
// [analyzer] COMPILE_TIME_ERROR.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER
// ^^^^^^^^^^^^^^^^^^^
// [cfe] The class 'AbiSpecificInteger' can't be implemented outside of its library because it's a base class.
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_STRUCT_CLASS
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
// [analyzer] COMPILE_TIME_ERROR.INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
const AbiSpecificInteger4();
}
class MyFinalizableStruct extends Struct implements Finalizable {
// ^^^^^^^^^^^^^^^^^^^
// [cfe] Struct 'MyFinalizableStruct' can't implement Finalizable.
// [analyzer] COMPILE_TIME_ERROR.COMPOUND_IMPLEMENTS_FINALIZABLE
Pointer<Void> field;
}