1 module contract.functions;
2 
3 
4 import contract;
5 import std.array: array;
6 
7 
8 // See #43
9 @Tags("contract")
10 @("functionproto.deref")
11 @safe unittest {
12 
13     const tu = parse(
14         C(
15             q{
16                 int binOp(int (f)(int x, int y), int a, int b);
17             }
18         )
19     );
20 
21     tu.children.length.should == 1;
22 
23     const binOp = tu.child(0);
24     binOp.shouldMatch(Cursor.Kind.FunctionDecl, "binOp");
25 
26     binOp.type.paramTypes.array.length.should == 3;
27     const f = binOp.type.paramTypes.array[0];
28     // need canonical for old versions of libclang
29     f.canonical.shouldMatch(Type.Kind.FunctionProto, "int (int, int)");
30     writelnUt(f.pointee);
31     // presumably, not a pointer
32     f.pointee.isInvalid.should == true;
33 }
34 
35 
36 @Tags("contract")
37 @("functionproto.star")
38 @safe unittest {
39 
40     const tu = parse(
41         C(
42             q{
43                 int binOp(int (*f)(int x, int y), int a, int b);
44             }
45         )
46     );
47 
48     tu.children.length.should == 1;
49 
50     const binOp = tu.child(0);
51     binOp.shouldMatch(Cursor.Kind.FunctionDecl, "binOp");
52 
53     binOp.type.paramTypes.array.length.should == 3;
54     const f = binOp.type.paramTypes.array[0];
55     // Even though the declaration here is effectively the same as the
56     // one in the test above, it shows up as a pointer
57     f.shouldMatch(Type.Kind.Pointer, "int (*)(int, int)");
58     writelnUt(f.pointee);
59     // it's a pointer
60     f.pointee.isInvalid.should == false;
61 
62     f.pointee.canonical.shouldMatch(Type.Kind.FunctionProto, "int (int, int)");
63 }