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 
109 struct ObjcCursor
110 {
111 	Cursor cursor;
112 	alias cursor this;
113 	
114 	@property ObjCInstanceMethodVisitor instanceMethods ()
115 	{
116 		return ObjCInstanceMethodVisitor(cursor);
117 	}
118 	
119 	@property ObjCClassMethodVisitor classMethods ()
120 	{
121 		return ObjCClassMethodVisitor(cursor);
122 	}
123 	
124 	@property ObjCPropertyVisitor properties ()
125 	{
126 		return ObjCPropertyVisitor(cursor);
127 	}
128 	
129 	@property Cursor superClass ()
130 	{
131 		foreach (cursor, parent ; TypedVisitor!(CXCursorKind.CXCursor_ObjCSuperClassRef)(cursor))
132 			return cursor;
133 
134 		return Cursor.empty;
135 	}
136 	
137 	@property ObjCProtocolVisitor protocols ()
138 	{
139 		return ObjCProtocolVisitor(cursor);
140 	}
141 
142 	@property Cursor category ()
143 	{
144 		assert(cursor.kind == CXCursorKind.CXCursor_ObjCCategoryDecl);
145 
146 		foreach (c, _ ; TypedVisitor!(CXCursorKind.CXCursor_ObjCClassRef)(cursor))
147 			return c;
148 
149 		assert(0, "This cursor does not have a class reference.");
150 	}
151 }
152 
153 struct FunctionCursor
154 {
155 	Cursor cursor;
156 	alias cursor this;
157 	
158 	@property Type resultType ()
159 	{
160 		auto r = clang_getCursorResultType(cx);
161 		return Type(r);
162 	}
163 	
164 	@property bool isVariadic ()
165 	{
166 		return type.func.isVariadic;
167 	}
168 	
169 	@property ParamVisitor parameters ()
170 	{
171 		return ParamVisitor(cx);
172 	}
173 }
174 
175 struct ParamCursor
176 {
177 	Cursor cursor;
178 	alias cursor this;
179 }
180 
181 struct EnumCursor
182 {
183 	Cursor cursor;
184 	alias cursor this;
185 
186 	@property string value ()
187 	{
188 		//return type.kind.isUnsigned ? unsignedValue.toString : signedValue.toString;
189 		return signedValue.toString;
190 	}
191 	
192 	@property long signedValue ()
193 	{
194 		return clang_getEnumConstantDeclValue(cx);
195 	}
196 
197 	@property ulong unsignedValue ()
198 	{
199 		return clang_getEnumConstantDeclUnsignedValue(cx);
200 	}
201 }