1 module parse.cooked; 2 3 import test.infra; 4 import clang; 5 6 @("visitChildren C++ file with one simple struct") 7 @safe unittest { 8 with(NewTranslationUnit("foo.cpp", 9 q{ struct Struct { int int_; double double_; }; })) 10 { 11 translUnit.cursor.visitChildren( 12 (cursor, parent) { 13 14 static int cursorIndex; 15 16 switch(cursorIndex) { 17 18 default: 19 assert(false); 20 21 case 0: 22 cursor.kind.shouldEqual(Cursor.Kind.StructDecl); 23 parent.kind.shouldEqual(Cursor.Kind.TranslationUnit); 24 break; 25 26 case 1: 27 cursor.kind.shouldEqual(Cursor.Kind.FieldDecl); 28 parent.kind.shouldEqual(Cursor.Kind.StructDecl); 29 break; 30 31 case 2: 32 cursor.kind.shouldEqual(Cursor.Kind.FieldDecl); 33 parent.kind.shouldEqual(Cursor.Kind.StructDecl); 34 break; 35 } 36 37 ++cursorIndex; 38 39 40 return ChildVisitResult.Recurse; 41 } 42 ); 43 } 44 } 45 46 47 @("visitChildren C++ file with one simple struct and throwing visitor") 48 @safe unittest { 49 with(NewTranslationUnit("foo.cpp", 50 q{ struct Struct { int int_; double double_; }; })) 51 { 52 translUnit.cursor.visitChildren( 53 (cursor, parent) { 54 int i; 55 if(i % 2 == 0) 56 throw new Exception("oops"); 57 return ChildVisitResult.Recurse; 58 } 59 ).shouldThrowWithMessage("oops"); 60 } 61 62 } 63 64 @("foreach(cursor, parent) C++ file with one simple struct") 65 @safe unittest { 66 with(NewTranslationUnit("foo.cpp", 67 q{ struct Struct { int int_; double double_; }; })) 68 { 69 foreach(cursor, parent; translUnit.cursor) { 70 71 static int cursorIndex; 72 73 switch(cursorIndex) { 74 75 default: 76 assert(false); 77 78 case 0: 79 cursor.kind.shouldEqual(Cursor.Kind.StructDecl); 80 parent.kind.shouldEqual(Cursor.Kind.TranslationUnit); 81 break; 82 83 case 1: 84 cursor.kind.shouldEqual(Cursor.Kind.FieldDecl); 85 parent.kind.shouldEqual(Cursor.Kind.StructDecl); 86 break; 87 88 case 2: 89 cursor.kind.shouldEqual(Cursor.Kind.FieldDecl); 90 parent.kind.shouldEqual(Cursor.Kind.StructDecl); 91 break; 92 } 93 94 ++cursorIndex; 95 } 96 } 97 } 98 99 @("foreach(cursor) C++ file with one simple struct") 100 @safe unittest { 101 with(NewTranslationUnit("foo.cpp", 102 q{ struct Struct { int int_; double double_; }; })) 103 { 104 foreach(cursor; translUnit.cursor) { 105 106 static int cursorIndex; 107 108 switch(cursorIndex) { 109 110 default: 111 assert(false); 112 113 case 0: 114 cursor.kind.shouldEqual(Cursor.Kind.StructDecl); 115 break; 116 117 case 1: 118 cursor.kind.shouldEqual(Cursor.Kind.FieldDecl); 119 break; 120 121 case 2: 122 cursor.kind.shouldEqual(Cursor.Kind.FieldDecl); 123 break; 124 } 125 126 ++cursorIndex; 127 } 128 } 129 } 130 131 @("cursor.children C++ file with one simple struct") 132 @safe unittest { 133 import std.algorithm: map; 134 135 with(NewTranslationUnit("foo.cpp", 136 q{ struct Struct { int int_; double double_; }; })) 137 { 138 const cursor = translUnit.cursor; 139 with(Cursor.Kind) { 140 cursor.children.map!(a => a.kind).shouldEqual([StructDecl]); 141 cursor.children[0].children.map!(a => a.kind).shouldEqual( 142 [FieldDecl, FieldDecl] 143 ); 144 } 145 } 146 } 147 148 @("Function return type should have valid cx") 149 @safe unittest { 150 import clang.c.index: CXType_Pointer; 151 with(NewTranslationUnit("foo.cpp", 152 q{ 153 const char* newString(); 154 })) 155 { 156 const cursor = translUnit.cursor; 157 cursor.children.length.shouldEqual(1); 158 const function_ = cursor.children[0]; 159 function_.kind.shouldEqual(Cursor.Kind.FunctionDecl); 160 function_.returnType.kind.shouldEqual(Type.Kind.Pointer); 161 function_.returnType.cx.kind.shouldEqual(CXType_Pointer); 162 } 163 164 }