Skip to content

Commit a67c79b

Browse files
dcharkesCommit Queue
authored and
Commit Queue
committed
[analyzer/ffi] Native static checks
Bug: #49803 Bug: #50097 Change-Id: Id5b52be88937bcf9245f98e71afa56f079f288f0 Cq-Include-Trybots: luci.dart.try:analyzer-linux-release-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/265085 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Daco Harkes <[email protected]>
1 parent ea70de3 commit a67c79b

File tree

3 files changed

+177
-1
lines changed

3 files changed

+177
-1
lines changed

pkg/analyzer/lib/src/generated/ffi_verifier.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,8 @@ extension on Annotation {
13231323
final element = this.element;
13241324
return element is ConstructorElement &&
13251325
element.ffiClass != null &&
1326-
element.enclosingElement.name == 'FfiNative';
1326+
(element.enclosingElement.name == 'Native' ||
1327+
element.enclosingElement.name == 'FfiNative');
13271328
}
13281329

13291330
bool get isPacked {

pkg/analyzer/lib/src/test_utilities/mock_sdk.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,23 @@ class FfiNative<T> {
827827
const FfiNative(this.nativeName, {this.isLeaf: false});
828828
}
829829
830+
class Native<T> {
831+
final String? symbol;
832+
final String? asset;
833+
final bool isLeaf;
834+
835+
const Native({
836+
this.asset,
837+
this.isLeaf: false,
838+
this.symbol,
839+
});
840+
}
841+
842+
class Asset {
843+
final String asset;
844+
const Asset(this.asset);
845+
}
846+
830847
class Abi {
831848
static const androidArm = _androidArm;
832849
static const androidArm64 = _androidArm64;

pkg/analyzer/test/src/diagnostics/ffi_native_test.dart

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import '../dart/resolution/context_collection_resolution.dart';
1111
main() {
1212
defineReflectiveSuite(() {
1313
defineReflectiveTests(FfiNativeTest);
14+
defineReflectiveTests(NativeTest);
1415
});
1516
}
1617

@@ -182,3 +183,160 @@ external double wrongFfiReturnType(int v);
182183
]);
183184
}
184185
}
186+
187+
@reflectiveTest
188+
class NativeTest extends PubPackageResolutionTest {
189+
test_annotation_Native_getters() async {
190+
await assertNoErrorsInCode(r'''
191+
import 'dart:ffi';
192+
193+
class NativeFieldWrapperClass1 {}
194+
195+
class Paragraph extends NativeFieldWrapperClass1 {
196+
@Native<Double Function(Pointer<Void>)>(isLeaf: true)
197+
external double get ideographicBaseline;
198+
199+
@Native<Void Function(Pointer<Void>, Double)>(isLeaf: true)
200+
external set ideographicBaseline(double d);
201+
}
202+
''');
203+
}
204+
205+
test_annotation_Native_noArguments() async {
206+
await assertErrorsInCode(r'''
207+
import 'dart:ffi';
208+
209+
@Native
210+
external int foo();
211+
''', [
212+
error(CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS, 20, 7),
213+
]);
214+
}
215+
216+
test_NativeCanUseHandles() async {
217+
await assertErrorsInCode(r'''
218+
import 'dart:ffi';
219+
@Native<Handle Function(Handle)>()
220+
external Object doesntMatter(Object);
221+
''', []);
222+
}
223+
224+
test_NativeCanUseLeaf() async {
225+
await assertErrorsInCode(r'''
226+
import 'dart:ffi';
227+
@Native<Int8 Function(Int64)>(isLeaf:true)
228+
external int doesntMatter(int x);
229+
''', []);
230+
}
231+
232+
test_NativeInstanceMethodsMustHaveReceiver() async {
233+
await assertErrorsInCode(r'''
234+
import 'dart:ffi';
235+
class K {
236+
@Native<Void Function(Double)>()
237+
external void doesntMatter(double x);
238+
}
239+
''', [
240+
error(FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS_WITH_RECEIVER,
241+
31, 72),
242+
]);
243+
}
244+
245+
test_NativeLeafMustNotReturnHandle() async {
246+
await assertErrorsInCode(r'''
247+
import 'dart:ffi';
248+
@Native<Handle Function()>(isLeaf:true)
249+
external Object doesntMatter();
250+
''', [
251+
error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 19, 71),
252+
]);
253+
}
254+
255+
test_NativeLeafMustNotTakeHandles() async {
256+
await assertErrorsInCode(r'''
257+
import 'dart:ffi';
258+
@Native<Void Function(Handle)>(symbol: 'DoesntMatter', isLeaf:true)
259+
external void doesntMatter(Object o);
260+
''', [
261+
error(FfiCode.LEAF_CALL_MUST_NOT_TAKE_HANDLE, 19, 105),
262+
]);
263+
}
264+
265+
test_NativeNonFfiParameter() async {
266+
await assertErrorsInCode(r'''
267+
import 'dart:ffi';
268+
@Native<IntPtr Function(int)>()
269+
external int nonFfiParameter(int v);
270+
''', [
271+
error(FfiCode.MUST_BE_A_NATIVE_FUNCTION_TYPE, 19, 68),
272+
]);
273+
}
274+
275+
test_NativeNonFfiReturnType() async {
276+
await assertErrorsInCode(r'''
277+
import 'dart:ffi';
278+
@Native<double Function(IntPtr)>()
279+
external double nonFfiReturnType(int v);
280+
''', [
281+
error(FfiCode.MUST_BE_A_NATIVE_FUNCTION_TYPE, 19, 75),
282+
]);
283+
}
284+
285+
test_NativePointerParameter() async {
286+
await assertNoErrorsInCode(r'''
287+
import 'dart:ffi';
288+
@Native<Void Function(Pointer)>()
289+
external void free(Pointer pointer);
290+
''');
291+
}
292+
293+
test_NativeTooFewParameters() async {
294+
await assertErrorsInCode(r'''
295+
import 'dart:ffi';
296+
@Native<Void Function(Double)>()
297+
external void doesntMatter(double x, double y);
298+
''', [
299+
error(FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS, 19, 80),
300+
]);
301+
}
302+
303+
test_NativeTooManyParameters() async {
304+
await assertErrorsInCode(r'''
305+
import 'dart:ffi';
306+
@Native<Void Function(Double, Double)>()
307+
external void doesntMatter(double x);
308+
''', [
309+
error(FfiCode.FFI_NATIVE_UNEXPECTED_NUMBER_OF_PARAMETERS, 19, 78),
310+
]);
311+
}
312+
313+
test_NativeVoidReturn() async {
314+
await assertErrorsInCode(r'''
315+
import 'dart:ffi';
316+
@Native<Handle Function(Uint32, Uint32, Handle)>()
317+
external void voidReturn(int width, int height, Object outImage);
318+
''', [
319+
error(FfiCode.MUST_BE_A_SUBTYPE, 19, 116),
320+
]);
321+
}
322+
323+
test_NativeWrongFfiParameter() async {
324+
await assertErrorsInCode(r'''
325+
import 'dart:ffi';
326+
@Native<IntPtr Function(Double)>()
327+
external int wrongFfiParameter(int v);
328+
''', [
329+
error(FfiCode.MUST_BE_A_SUBTYPE, 19, 73),
330+
]);
331+
}
332+
333+
test_NativeWrongFfiReturnType() async {
334+
await assertErrorsInCode(r'''
335+
import 'dart:ffi';
336+
@Native<IntPtr Function(IntPtr)>()
337+
external double wrongFfiReturnType(int v);
338+
''', [
339+
error(FfiCode.MUST_BE_A_SUBTYPE, 19, 77),
340+
]);
341+
}
342+
}

0 commit comments

Comments
 (0)