1 /**
2  * Copyright: Copyright (c) 2011 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Jan 1, 2012
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  */
7 module clang.Cursor;
8 
9 import mambo.core._;
10 
11 import clang.c.Index;
12 import clang.SourceLocation;
13 import clang.Type;
14 import clang.Util;
15 import clang.Visitor;
16 
17 struct Cursor
18 {
19     mixin CX;
20 
21     @property static Cursor empty ()
22     {
23         auto r = clang_getNullCursor();
24         return Cursor(r);
25     }
26 
27     @property string spelling ()
28     {
29         return toD(clang_getCursorSpelling(cx));
30     }
31 
32     @property CXCursorKind kind ()
33     {
34         return clang_getCursorKind(cx);
35     }
36 
37     @property SourceLocation location ()
38     {
39         return SourceLocation(clang_getCursorLocation(cx));
40     }
41 
42     @property Type type ()
43     {
44         auto r = clang_getCursorType(cx);
45         return Type(r);
46     }
47 
48     @property bool isDeclaration ()
49     {
50         return clang_isDeclaration(cx.kind) != 0;
51     }
52 
53     @property DeclarationVisitor declarations ()
54     {
55         return DeclarationVisitor(cx);
56     }
57 
58     @property ObjcCursor objc ()
59     {
60         return ObjcCursor(this);
61     }
62 
63     @property FunctionCursor func ()
64     {
65         return FunctionCursor(this);
66     }
67 
68     @property EnumCursor enum_ ()
69     {
70         return EnumCursor(this);
71     }
72 
73     @property bool isValid ()
74     {
75         return !clang_isInvalid(cx.kind);
76     }
77 
78     @property bool isEmpty ()
79     {
80         return clang_Cursor_isNull(cx) != 0;
81     }
82 
83     @property Visitor all ()
84     {
85         return Visitor(this);
86     }
87 
88     @property CXLanguageKind language ()
89     {
90         return clang_getCursorLanguage(cx);
91     }
92 
93     equals_t opEquals (const ref Cursor cursor) const
94     {
95         return clang_equalCursors(cast(CXCursor) cursor.cx, cast(CXCursor) cx) != 0;
96     }
97 
98     hash_t toHash () const
99     {
100         return clang_hashCursor(cast(CXCursor) cx);
101     }
102 
103     bool isDefinition () const
104     {
105         return clang_isCursorDefinition(cast(CXCursor) cx) != 0;
106     }
107 
108     @property Cursor definition () const
109     {
110         return Cursor(clang_getCursorDefinition(cast(CXCursor) cx));
111     }
112 }
113 
114 struct ObjcCursor
115 {
116     Cursor cursor;
117     alias cursor this;
118 
119     @property ObjCInstanceMethodVisitor instanceMethods ()
120     {
121         return ObjCInstanceMethodVisitor(cursor);
122     }
123 
124     @property ObjCClassMethodVisitor classMethods ()
125     {
126         return ObjCClassMethodVisitor(cursor);
127     }
128 
129     @property ObjCPropertyVisitor properties ()
130     {
131         return ObjCPropertyVisitor(cursor);
132     }
133 
134     @property Cursor superClass ()
135     {
136         foreach (cursor, parent ; TypedVisitor!(CXCursorKind.CXCursor_ObjCSuperClassRef)(cursor))
137             return cursor;
138 
139         return Cursor.empty;
140     }
141 
142     @property ObjCProtocolVisitor protocols ()
143     {
144         return ObjCProtocolVisitor(cursor);
145     }
146 
147     @property Cursor category ()
148     {
149         assert(cursor.kind == CXCursorKind.CXCursor_ObjCCategoryDecl);
150 
151         foreach (c, _ ; TypedVisitor!(CXCursorKind.CXCursor_ObjCClassRef)(cursor))
152             return c;
153 
154         assert(0, "This cursor does not have a class reference.");
155     }
156 }
157 
158 struct FunctionCursor
159 {
160     Cursor cursor;
161     alias cursor this;
162 
163     @property Type resultType ()
164     {
165         auto r = clang_getCursorResultType(cx);
166         return Type(r);
167     }
168 
169     @property bool isVariadic ()
170     {
171         return type.func.isVariadic;
172     }
173 
174     @property ParamVisitor parameters ()
175     {
176         return ParamVisitor(cx);
177     }
178 }
179 
180 struct ParamCursor
181 {
182     Cursor cursor;
183     alias cursor this;
184 }
185 
186 struct EnumCursor
187 {
188     Cursor cursor;
189     alias cursor this;
190 
191     @property string value ()
192     {
193         //return type.kind.isUnsigned ? unsignedValue.toString : signedValue.toString;
194         return signedValue.toString;
195     }
196 
197     @property long signedValue ()
198     {
199         return clang_getEnumConstantDeclValue(cx);
200     }
201 
202     @property ulong unsignedValue ()
203     {
204         return clang_getEnumConstantDeclUnsignedValue(cx);
205     }
206 }