blob: d7cd9f3ac0d573ffb69d2aa2f9079da2853c346e [file] [log] [blame]
// 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
import 'dart:ffi';
import "package:ffi/ffi.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();
testNativeCallableListenerGeneric();
testNativeCallableListenerGeneric2();
testNativeCallableListenerWrongNativeFunctionSignature();
testNativeCallableListenerTypeMismatch();
testNativeCallableListenerAbstract();
testNativeCallableListenerMustReturnVoid();
testNativeCallableIsolateLocalGeneric();
testNativeCallableIsolateLocalGeneric2();
testNativeCallableIsolateLocalWrongNativeFunctionSignature();
testNativeCallableIsolateLocalTypeMismatch();
testNativeCallableIsolateLocalTearOff();
testNativeCallableIsolateLocalAbstract();
testNativeCallableIsolateLocalFunctionExceptionValueMustBeConst();
testLookupFunctionGeneric();
testLookupFunctionGeneric2();
testLookupFunctionWrongNativeFunctionSignature();
testLookupFunctionTypeMismatch();
testLookupFunctionPointervoid();
testLookupFunctionPointerNFdyn();
testHandleVariance();
testEmptyStructLookupFunctionArgument();
testEmptyStructLookupFunctionReturn();
testEmptyStructAsFunctionArgument();
testEmptyStructAsFunctionReturn();
testEmptyStructFromFunctionArgument();
testEmptyStructFromFunctionReturn();
testAllocateGeneric();
testAllocateInvalidType();
testCreateInvalidType();
testRefStruct();
testSizeOfGeneric();
testSizeOfInvalidType();
testElementAtGeneric();
testElementAtNativeType();
testLookupFunctionIsLeafMustBeConst();
testAsFunctionIsLeafMustBeConst();
testLookupFunctionTakesHandle();
testAsFunctionTakesHandle();
testLookupFunctionReturnsHandle();
testAsFunctionReturnsHandle();
testReturnVoidNotVoid();
}
typedef Int8UnOp = Int8 Function(Int8);
typedef IntUnOp = int Function(int);
void testGetGeneric() {
int generic(Pointer p) {
int result = -1;
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>(T defaultFunction) {
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
T f = defaultFunction;
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>((int a) => a + 1);
}
void testAsFunctionGeneric2() {
generic(Pointer<NativeFunction> p) {
Function f = () => "dummy";
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] Non-nullable variable 'p' must be assigned before it can be used.
// [analyzer] COMPILE_TIME_ERROR.NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE
// ^
// [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)>'.
}
void testFunctionNotFunctionType() {
Pointer<NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
Function f = p.asFunction();
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'Function' 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 = nullptr;
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 = nullptr;
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.
}
typedef NativeVoidFunc = Void Function();
typedef VoidFunc = void Function();
void myVoidFunc() {
print("Hello World");
}
void myVoidFunc2(int x) {
print("x = $x");
}
void testNativeCallableListenerGeneric() {
NativeCallable? generic<T extends Function>(T f) {
NativeCallable<NativeVoidFunc>? result;
result = NativeCallable.listener(f);
// ^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'T' to be 'void Function()', which is the Dart type corresponding to 'NativeFunction<Void Function()>'.
return result;
}
generic(myVoidFunc);
}
void testNativeCallableListenerGeneric2() {
NativeCallable<T>? generic<T extends Function>() {
NativeCallable<T>? result;
result = NativeCallable.listener(myVoidFunc);
// ^^^^^^^^^^^^^^^^^^^^^^^
// [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<NativeVoidFunc>();
}
void testNativeCallableListenerWrongNativeFunctionSignature() {
/**/ NativeCallable<NativeVoidFunc>.listener(myVoidFunc2);
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'void Function(int)' to be 'void Function()', which is the Dart type corresponding to 'NativeFunction<Void Function()>'.
}
void testNativeCallableListenerTypeMismatch() {
NativeCallable<NativeVoidFunc> p;
p = NativeCallable.listener(myVoidFunc2);
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
// ^
// [cfe] Expected type 'void Function(int)' to be 'void Function()', which is the Dart type corresponding to 'NativeFunction<Void Function()>'.
}
void testNativeCallableListenerAbstract() {
final f = NativeCallable<Function>.listener(
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [cfe] Expected type 'NativeFunction<Function>' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
testNativeCallableListenerAbstract);
}
void testNativeCallableListenerMustReturnVoid() {
final f = NativeCallable<NativeDoubleUnOp>.listener(myTimesThree);
// ^^^^^^^^^^^^
// [cfe] The return type of the function passed to NativeCallable.listener must be void rather than 'double'.
// [analyzer] COMPILE_TIME_ERROR.MUST_RETURN_VOID
}
void testNativeCallableIsolateLocalGeneric() {
NativeCallable<Function> generic<T extends Function>(T f) {
late NativeCallable<NativeDoubleUnOp> result;
result = NativeCallable.isolateLocal(f);
// ^
// [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(myTimesThree);
}
void testNativeCallableIsolateLocalGeneric2() {
NativeCallable<T> generic<T extends Function>() {
late NativeCallable<T> result;
result = NativeCallable.isolateLocal(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 testNativeCallableIsolateLocalWrongNativeFunctionSignature() {
/**/ NativeCallable<IntUnOp>.isolateLocal(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 testNativeCallableIsolateLocalTypeMismatch() {
NativeCallable<NativeDoubleUnOp> p;
p = NativeCallable.isolateLocal(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 testNativeCallableIsolateLocalTearOff() {
DoubleUnOp fld = X().tearoff;
NativeCallable<NativeDoubleUnOp> p;
p = NativeCallable.isolateLocal(fld);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISSING_EXCEPTION_VALUE
// ^
// [cfe] Expected an exceptional return value for a native callback returning 'double'.
}
void testNativeCallableIsolateLocalAbstract() {
NativeCallable<Function>.isolateLocal(testNativeCallableIsolateLocalAbstract);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [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 testNativeCallableIsolateLocalFunctionExceptionValueMustBeConst() {
final notAConst = 1.1;
NativeCallable<NativeDoubleUnOp> p;
p = NativeCallable.isolateLocal(myTimesThree, exceptionalReturn: 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 = DynamicLibrary.process();
Function result = () => "dummy";
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 = DynamicLibrary.process();
Function result = () => "dummy";
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 = DynamicLibrary.process();
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 = DynamicLibrary.process();
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 = DynamicLibrary.process();
// 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 = DynamicLibrary.process();
// TODO(https://dartbug.com/44594): Should this be an error or not?
// l.lookupFunction<PointerNFdynN, PointerNFdynD>("cos");
}
// error on missing field annotation
final class TestStruct extends Struct {
@Double()
external double x;
external 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.
// [cfe] The type 'TestStruct3' must be 'base', 'final' or 'sealed' because the supertype 'TestStruct' is 'final'.
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_STRUCT_CLASS
// error on double annotation
final class TestStruct4 extends Struct {
@Double()
/**/ @Double()
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTRA_ANNOTATION_ON_STRUCT_FIELD
external 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
final class TestStruct5 extends Struct {
/**/ @Int64()
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISMATCHED_ANNOTATION_ON_STRUCT_FIELD
external double z;
// ^
// [cfe] Expected type 'double' to be 'int', which is the Dart type corresponding to 'Int64'.
external Pointer notEmpty;
}
// error on annotation not matching up
final 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.
external 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.
external Pointer notEmpty;
}
// error on annotation not matching up
final class TestStruct7 extends Struct {
/**/ @Int8()
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISMATCHED_ANNOTATION_ON_STRUCT_FIELD
external double y;
// ^
// [cfe] Expected type 'double' to be 'int', which is the Dart type corresponding to 'Int8'.
external double z;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISSING_ANNOTATION_ON_STRUCT_FIELD
// ^
// [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.
external Pointer notEmpty;
}
// error on field initializer on field
final 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_MUST_BE_EXTERNAL_IN_STRUCT
external Pointer notEmpty;
}
// error on field initializer in constructor
final 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.
// [analyzer] COMPILE_TIME_ERROR.FIELD_MUST_BE_EXTERNAL_IN_STRUCT
external 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.
}
// 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
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [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).
final 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.
external TestStruct9 struct;
external Pointer notEmpty;
}
class DummyAnnotation {
const DummyAnnotation();
}
// Structs fields may have other annotations.
final class TestStruct13 extends Struct {
@DummyAnnotation()
@Double()
external 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.
// [cfe] Subtypes of deeply immutable classes must be deeply immutable.
// 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:
// [cfe] Subtypes of deeply immutable classes must be deeply immutable.
// [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 type 'IStruct' must be 'base', 'final' or 'sealed' because the supertype 'Struct' is 'base'.
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// ^^^^^^
// [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 type 'IOpaque' must be 'base', 'final' or 'sealed' because the supertype 'Opaque' is 'base'.
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// ^^^^^^
// [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 = DynamicLibrary.process();
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");
}
final class TestStruct1001 extends Struct {
external 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.
external Pointer notEmpty;
}
final class TestStruct1002 extends Struct {
/**/ @Handle()
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_ANNOTATION_CONSTRUCTOR
// ^
// [cfe] The class 'Handle' is abstract and can't be instantiated.
external 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.
external Pointer notEmpty;
}
final class EmptyStruct extends Struct {}
// ^^^^^^^^^^^
// [cfe] Struct 'EmptyStruct' is empty. Empty structs and unions are undefined behavior.
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
void testEmptyStructLookupFunctionArgument() {
testLibrary.lookupFunction<
/**/ Void Function(EmptyStruct),
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
void Function(EmptyStruct)>("DoesNotExist");
}
void testEmptyStructLookupFunctionReturn() {
testLibrary.lookupFunction<EmptyStruct Function(), EmptyStruct Function()>(
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
"DoesNotExist");
}
void testEmptyStructAsFunctionArgument() {
final Pointer<NativeFunction<Void Function(EmptyStruct)>> pointer =
Pointer.fromAddress(1234);
pointer.asFunction<void Function(EmptyStruct)>();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER
}
void testEmptyStructAsFunctionReturn() {
final Pointer<NativeFunction<EmptyStruct Function()>> pointer =
Pointer.fromAddress(1234);
pointer.asFunction<EmptyStruct Function()>();
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER
}
void _consumeEmptyStruct(EmptyStruct e) => print(e);
void testEmptyStructFromFunctionArgument() {
Pointer.fromFunction<Void Function(EmptyStruct)>(_consumeEmptyStruct);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
}
/**/ EmptyStruct _returnEmptyStruct() => EmptyStruct();
// ^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CREATION_OF_STRUCT_OR_UNION
// [cfe] Subclasses of 'Struct' and 'Union' are backed by native memory, and can't be instantiated by a generative constructor. Try allocating it via allocation, or load from a 'Pointer'.
void testEmptyStructFromFunctionReturn() {
Pointer.fromFunction<EmptyStruct Function()>(_returnEmptyStruct);
// ^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_NATIVE_FUNCTION_TYPE
}
final class HasNestedEmptyStruct extends Struct {
external EmptyStruct nestedEmptyStruct;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EMPTY_STRUCT
external Pointer notEmpty;
}
void testAllocateGeneric() {
Pointer<T> generic<T extends SizedNativeType>() {
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 testAllocateInvalidType() {
/**/ calloc();
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'SizedNativeType' to be a valid and instantiated subtype of 'NativeType'.
/**/ calloc<Struct>();
// ^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'Struct' to be a valid and instantiated subtype of 'NativeType'.
/**/ calloc<Union>();
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'Union' to be a valid and instantiated subtype of 'NativeType'.
/**/ calloc<AbiSpecificInteger>();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'AbiSpecificInteger' to be a valid and instantiated subtype of 'NativeType'.
}
// TODO(https://dartbug.com/36780): Improve error messages.
void testCreateInvalidType() {
/**/ Struct.create<Struct>();
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'Struct' to be a valid and instantiated subtype of 'NativeType'.
/**/ Union.create<Union>();
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
// ^
// [cfe] Expected type 'Union' 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 testSizeOfInvalidType() {
sizeOf();
//^^^^^^^^
// [cfe] Expected type 'SizedNativeType' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
sizeOf<Struct>();
//^^^^^^^^^^^^^^^^
// [cfe] Expected type 'Struct' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
sizeOf<Union>();
//^^^^^^^^^^^^^^^
// [cfe] Expected type 'Union' to be a valid and instantiated subtype of 'NativeType'.
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
sizeOf<AbiSpecificInteger>();
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [cfe] Expected type 'AbiSpecificInteger' 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);
}
final class TestStruct1400 extends Struct {
@Array(8)
@Array(8)
//^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTRA_SIZE_ANNOTATION_CARRAY
external Array<Uint8> a0;
// ^
// [cfe] Field 'a0' must have exactly one 'Array' annotation.
}
final class TestStruct1401 extends Struct {
external Array<Uint8> a0;
// ^
// [cfe] Field 'a0' must have exactly one 'Array' annotation.
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MISSING_SIZE_ANNOTATION_CARRAY
external Pointer<Uint8> notEmpty;
}
final class TestStruct1402 extends Struct {
/**/ @Array(8, 8, 8)
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
external Array<Array<Uint8>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
external Pointer<Uint8> notEmpty;
}
final class TestStruct1403 extends Struct {
/**/ @Array(8, 8)
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
external Array<Array<Array<Uint8>>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
external Pointer<Uint8> notEmpty;
}
final class TestStruct1404 extends Struct {
/**/ @Array.multi([8, 8, 8])
// ^^^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
external Array<Array<Uint8>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
external Pointer<Uint8> notEmpty;
}
final class TestStruct1405 extends Struct {
/**/ @Array.multi([8, 8])
// ^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
external Array<Array<Array<Uint8>>> a0;
// ^
// [cfe] Field 'a0' must have an 'Array' annotation that matches the dimensions.
external Pointer<Uint8> notEmpty;
}
void testLookupFunctionIsLeafMustBeConst() {
bool notAConst = false;
DynamicLibrary l = DynamicLibrary.process();
/**/ 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 = DynamicLibrary.process();
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 = DynamicLibrary.process();
/**/ 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)
final class TestStruct1600 extends Struct {
external Pointer<Uint8> notEmpty;
}
@Packed(1)
/**/ @Packed(1)
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.PACKED_ANNOTATION
final class TestStruct1601 extends Struct {
// ^
// [cfe] Struct 'TestStruct1601' must have at most one 'Packed' annotation.
external Pointer<Uint8> notEmpty;
}
@Packed(3)
// ^
// [analyzer] COMPILE_TIME_ERROR.PACKED_ANNOTATION_ALIGNMENT
final class TestStruct1602 extends Struct {
// ^
// [cfe] Only packing to 1, 2, 4, 8, and 16 bytes is supported.
external Pointer<Uint8> notEmpty;
}
@Packed(0)
// ^
// [analyzer] COMPILE_TIME_ERROR.PACKED_ANNOTATION_ALIGNMENT
final class TestStruct1607 extends Struct {
// ^
// [cfe] Only packing to 1, 2, 4, 8, and 16 bytes is supported.
external Pointer<Uint8> notEmpty;
}
final class TestStruct1800 extends Struct {
external Pointer<Uint8> notEmpty;
@Array(-1)
// ^^
// [analyzer] COMPILE_TIME_ERROR.NON_POSITIVE_ARRAY_DIMENSION
external Array<Uint8> inlineArray;
// ^
// [cfe] Array dimensions must be positive numbers.
}
final class TestStruct1801 extends Struct {
external Pointer<Uint8> notEmpty;
/**/ @Array(1, -1)
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SIZE_ANNOTATION_DIMENSIONS
// ^^
// [analyzer] COMPILE_TIME_ERROR.NON_POSITIVE_ARRAY_DIMENSION
external Array<Uint8> inlineArray;
// ^
// [cfe] Array dimensions must be positive numbers.
// [cfe] Field 'inlineArray' must have an 'Array' annotation that matches the dimensions.
}
final class TestStruct1802 extends Struct {
external 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
external 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
final 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
int get a => 4;
external int b;
}
class AbiSpecificInteger2 implements AbiSpecificInteger {
// ^^^^^^^^^^^^^^^^^^^
// [cfe] Class 'Object' cannot be extended or implemented.
// [cfe] The type 'AbiSpecificInteger2' must be 'base', 'final' or 'sealed' because the supertype 'AbiSpecificInteger' is 'base'.
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// ^^^^^^^^^^^^^^^^^^
// [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_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// ^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_STRUCT_CLASS
// ^
// [cfe] The type 'AbiSpecificInteger3' must be 'base', 'final' or 'sealed' because the supertype 'AbiSpecificInteger1' is 'final'.
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
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
// ^^^^^^^^^^^^^^^^^^^
// [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
// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_STRUCT_CLASS
// ^
// [cfe] The type 'AbiSpecificInteger4' must be 'base', 'final' or 'sealed' because the supertype 'AbiSpecificInteger1' is 'final'.
const AbiSpecificInteger4();
}
final class MyFinalizableStruct extends Struct implements Finalizable {
// ^^^^^^^^^^^^^^^^^^^
// [cfe] Struct 'MyFinalizableStruct' can't implement Finalizable.
// [analyzer] COMPILE_TIME_ERROR.COMPOUND_IMPLEMENTS_FINALIZABLE
external Pointer<Void> field;
}
void testReturnVoidNotVoid() {
// Taking a more specific argument is okay.
testLibrary.lookupFunction<Handle Function(), void Function()>("unused");
// ^
// [cfe] Expected type 'void Function()' to be 'Object Function()', which is the Dart type corresponding to 'NativeFunction<Handle Function()>'.
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MUST_BE_A_SUBTYPE
}