cindex.py revision 9d342ab031ba831263291a3bcda485e684508ea9
1#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
2#
3#                     The LLVM Compiler Infrastructure
4#
5# This file is distributed under the University of Illinois Open Source
6# License. See LICENSE.TXT for details.
7#
8#===------------------------------------------------------------------------===#
9
10r"""
11Clang Indexing Library Bindings
12===============================
13
14This module provides an interface to the Clang indexing library. It is a
15low-level interface to the indexing library which attempts to match the Clang
16API directly while also being "pythonic". Notable differences from the C API
17are:
18
19 * string results are returned as Python strings, not CXString objects.
20
21 * null cursors are translated to None.
22
23 * access to child cursors is done via iteration, not visitation.
24
25The major indexing objects are:
26
27  Index
28
29    The top-level object which manages some global library state.
30
31  TranslationUnit
32
33    High-level object encapsulating the AST for a single translation unit. These
34    can be loaded from .ast files or parsed on the fly.
35
36  Cursor
37
38    Generic object for representing a node in the AST.
39
40  SourceRange, SourceLocation, and File
41
42    Objects representing information about the input source.
43
44Most object information is exposed using properties, when the underlying API
45call is efficient.
46"""
47
48# TODO
49# ====
50#
51# o API support for invalid translation units. Currently we can't even get the
52#   diagnostics on failure because they refer to locations in an object that
53#   will have been invalidated.
54#
55# o fix memory management issues (currently client must hold on to index and
56#   translation unit, or risk crashes).
57#
58# o expose code completion APIs.
59#
60# o cleanup ctypes wrapping, would be nice to separate the ctypes details more
61#   clearly, and hide from the external interface (i.e., help(cindex)).
62#
63# o implement additional SourceLocation, SourceRange, and File methods.
64
65from ctypes import *
66
67def get_cindex_library():
68    # FIXME: It's probably not the case that the library is actually found in
69    # this location. We need a better system of identifying and loading the
70    # CIndex library. It could be on path or elsewhere, or versioned, etc.
71    import platform
72    name = platform.system()
73    if name == 'Darwin':
74        return cdll.LoadLibrary('libclang.dylib')
75    elif name == 'Windows':
76        return cdll.LoadLibrary('libclang.dll')
77    else:
78        return cdll.LoadLibrary('libclang.so')
79
80# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
81# object. This is a problem, because it means that from_parameter will see an
82# integer and pass the wrong value on platforms where int != void*. Work around
83# this by marshalling object arguments as void**.
84c_object_p = POINTER(c_void_p)
85
86lib = get_cindex_library()
87
88### Structures and Utility Classes ###
89
90class _CXString(Structure):
91    """Helper for transforming CXString results."""
92
93    _fields_ = [("spelling", c_char_p), ("free", c_int)]
94
95    def __del__(self):
96        _CXString_dispose(self)
97
98    @staticmethod
99    def from_result(res, fn, args):
100        assert isinstance(res, _CXString)
101        return _CXString_getCString(res)
102
103class SourceLocation(Structure):
104    """
105    A SourceLocation represents a particular location within a source file.
106    """
107    _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
108    _data = None
109
110    def _get_instantiation(self):
111        if self._data is None:
112            f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
113            SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
114            f = File(f) if f else None
115            self._data = (f, int(l.value), int(c.value), int(o.value))
116        return self._data
117
118    @property
119    def file(self):
120        """Get the file represented by this source location."""
121        return self._get_instantiation()[0]
122
123    @property
124    def line(self):
125        """Get the line represented by this source location."""
126        return self._get_instantiation()[1]
127
128    @property
129    def column(self):
130        """Get the column represented by this source location."""
131        return self._get_instantiation()[2]
132
133    @property
134    def offset(self):
135        """Get the file offset represented by this source location."""
136        return self._get_instantiation()[3]
137
138    def __repr__(self):
139        return "<SourceLocation file %r, line %r, column %r>" % (
140            self.file.name if self.file else None, self.line, self.column)
141
142class SourceRange(Structure):
143    """
144    A SourceRange describes a range of source locations within the source
145    code.
146    """
147    _fields_ = [
148        ("ptr_data", c_void_p * 2),
149        ("begin_int_data", c_uint),
150        ("end_int_data", c_uint)]
151
152    # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
153    # object.
154    @staticmethod
155    def from_locations(start, end):
156        return SourceRange_getRange(start, end)
157
158    @property
159    def start(self):
160        """
161        Return a SourceLocation representing the first character within a
162        source range.
163        """
164        return SourceRange_start(self)
165
166    @property
167    def end(self):
168        """
169        Return a SourceLocation representing the last character within a
170        source range.
171        """
172        return SourceRange_end(self)
173
174    def __repr__(self):
175        return "<SourceRange start %r, end %r>" % (self.start, self.end)
176
177class Diagnostic(object):
178    """
179    A Diagnostic is a single instance of a Clang diagnostic. It includes the
180    diagnostic severity, the message, the location the diagnostic occurred, as
181    well as additional source ranges and associated fix-it hints.
182    """
183
184    Ignored = 0
185    Note    = 1
186    Warning = 2
187    Error   = 3
188    Fatal   = 4
189
190    def __init__(self, ptr):
191        self.ptr = ptr
192
193    def __del__(self):
194        _clang_disposeDiagnostic(self)
195
196    @property
197    def severity(self):
198        return _clang_getDiagnosticSeverity(self)
199
200    @property
201    def location(self):
202        return _clang_getDiagnosticLocation(self)
203
204    @property
205    def spelling(self):
206        return _clang_getDiagnosticSpelling(self)
207
208    @property
209    def ranges(self):
210        class RangeIterator:
211            def __init__(self, diag):
212                self.diag = diag
213
214            def __len__(self):
215                return int(_clang_getDiagnosticNumRanges(self.diag))
216
217            def __getitem__(self, key):
218		if (key >= len(self)):
219			raise IndexError
220                return _clang_getDiagnosticRange(self.diag, key)
221
222        return RangeIterator(self)
223
224    @property
225    def fixits(self):
226        class FixItIterator:
227            def __init__(self, diag):
228                self.diag = diag
229
230            def __len__(self):
231                return int(_clang_getDiagnosticNumFixIts(self.diag))
232
233            def __getitem__(self, key):
234                range = SourceRange()
235                value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
236                if len(value) == 0:
237                    raise IndexError
238
239                return FixIt(range, value)
240
241        return FixItIterator(self)
242
243    def __repr__(self):
244        return "<Diagnostic severity %r, location %r, spelling %r>" % (
245            self.severity, self.location, self.spelling)
246
247    def from_param(self):
248      return self.ptr
249
250class FixIt(object):
251    """
252    A FixIt represents a transformation to be applied to the source to
253    "fix-it". The fix-it shouldbe applied by replacing the given source range
254    with the given value.
255    """
256
257    def __init__(self, range, value):
258        self.range = range
259        self.value = value
260
261    def __repr__(self):
262        return "<FixIt range %r, value %r>" % (self.range, self.value)
263
264### Cursor Kinds ###
265
266class CursorKind(object):
267    """
268    A CursorKind describes the kind of entity that a cursor points to.
269    """
270
271    # The unique kind objects, indexed by id.
272    _kinds = []
273    _name_map = None
274
275    def __init__(self, value):
276        if value >= len(CursorKind._kinds):
277            CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
278        if CursorKind._kinds[value] is not None:
279            raise ValueError,'CursorKind already loaded'
280        self.value = value
281        CursorKind._kinds[value] = self
282        CursorKind._name_map = None
283
284    def from_param(self):
285        return self.value
286
287    @property
288    def name(self):
289        """Get the enumeration name of this cursor kind."""
290        if self._name_map is None:
291            self._name_map = {}
292            for key,value in CursorKind.__dict__.items():
293                if isinstance(value,CursorKind):
294                    self._name_map[value] = key
295        return self._name_map[self]
296
297    @staticmethod
298    def from_id(id):
299        if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
300            raise ValueError,'Unknown cursor kind'
301        return CursorKind._kinds[id]
302
303    @staticmethod
304    def get_all_kinds():
305        """Return all CursorKind enumeration instances."""
306        return filter(None, CursorKind._kinds)
307
308    def is_declaration(self):
309        """Test if this is a declaration kind."""
310        return CursorKind_is_decl(self)
311
312    def is_reference(self):
313        """Test if this is a reference kind."""
314        return CursorKind_is_ref(self)
315
316    def is_expression(self):
317        """Test if this is an expression kind."""
318        return CursorKind_is_expr(self)
319
320    def is_statement(self):
321        """Test if this is a statement kind."""
322        return CursorKind_is_stmt(self)
323
324    def is_attribute(self):
325        """Test if this is an attribute kind."""
326        return CursorKind_is_attribute(self)
327
328    def is_invalid(self):
329        """Test if this is an invalid kind."""
330        return CursorKind_is_inv(self)
331
332    def __repr__(self):
333        return 'CursorKind.%s' % (self.name,)
334
335# FIXME: Is there a nicer way to expose this enumeration? We could potentially
336# represent the nested structure, or even build a class hierarchy. The main
337# things we want for sure are (a) simple external access to kinds, (b) a place
338# to hang a description and name, (c) easy to keep in sync with Index.h.
339
340###
341# Declaration Kinds
342
343# A declaration whose specific kind is not exposed via this interface.
344#
345# Unexposed declarations have the same operations as any other kind of
346# declaration; one can extract their location information, spelling, find their
347# definitions, etc. However, the specific kind of the declaration is not
348# reported.
349CursorKind.UNEXPOSED_DECL = CursorKind(1)
350
351# A C or C++ struct.
352CursorKind.STRUCT_DECL = CursorKind(2)
353
354# A C or C++ union.
355CursorKind.UNION_DECL = CursorKind(3)
356
357# A C++ class.
358CursorKind.CLASS_DECL = CursorKind(4)
359
360# An enumeration.
361CursorKind.ENUM_DECL = CursorKind(5)
362
363# A field (in C) or non-static data member (in C++) in a struct, union, or C++
364# class.
365CursorKind.FIELD_DECL = CursorKind(6)
366
367# An enumerator constant.
368CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
369
370# A function.
371CursorKind.FUNCTION_DECL = CursorKind(8)
372
373# A variable.
374CursorKind.VAR_DECL = CursorKind(9)
375
376# A function or method parameter.
377CursorKind.PARM_DECL = CursorKind(10)
378
379# An Objective-C @interface.
380CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
381
382# An Objective-C @interface for a category.
383CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
384
385# An Objective-C @protocol declaration.
386CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
387
388# An Objective-C @property declaration.
389CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
390
391# An Objective-C instance variable.
392CursorKind.OBJC_IVAR_DECL = CursorKind(15)
393
394# An Objective-C instance method.
395CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
396
397# An Objective-C class method.
398CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
399
400# An Objective-C @implementation.
401CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
402
403# An Objective-C @implementation for a category.
404CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
405
406# A typedef.
407CursorKind.TYPEDEF_DECL = CursorKind(20)
408
409# A C++ class method.
410CursorKind.CXX_METHOD = CursorKind(21)
411
412# A C++ namespace.
413CursorKind.NAMESPACE = CursorKind(22)
414
415# A linkage specification, e.g. 'extern "C"'.
416CursorKind.LINKAGE_SPEC = CursorKind(23)
417
418# A C++ constructor.
419CursorKind.CONSTRUCTOR = CursorKind(24)
420
421# A C++ destructor.
422CursorKind.DESTRUCTOR = CursorKind(25)
423
424# A C++ conversion function.
425CursorKind.CONVERSION_FUNCTION = CursorKind(26)
426
427# A C++ template type parameter
428CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27)
429
430# A C++ non-type template paramater.
431CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28)
432
433# A C++ template template parameter.
434CursorKind.TEMPLATE_TEMPLATE_PARAMTER = CursorKind(29)
435
436# A C++ function template.
437CursorKind.FUNCTION_TEMPLATE = CursorKind(30)
438
439# A C++ class template.
440CursorKind.CLASS_TEMPLATE = CursorKind(31)
441
442# A C++ class template partial specialization.
443CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32)
444
445# A C++ namespace alias declaration.
446CursorKind.NAMESPACE_ALIAS = CursorKind(33)
447
448# A C++ using directive
449CursorKind.USING_DIRECTIVE = CursorKind(34)
450
451# A C++ using declaration
452CursorKind.USING_DECLARATION = CursorKind(35)
453
454# A Type alias decl.
455CursorKind.TYPE_ALIAS_DECL = CursorKind(36)
456
457# A Objective-C synthesize decl
458CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37)
459
460# A Objective-C dynamic decl
461CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38)
462
463# A C++ access specifier decl.
464CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39)
465
466
467###
468# Reference Kinds
469
470CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
471CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
472CursorKind.OBJC_CLASS_REF = CursorKind(42)
473
474# A reference to a type declaration.
475#
476# A type reference occurs anywhere where a type is named but not
477# declared. For example, given:
478#   typedef unsigned size_type;
479#   size_type size;
480#
481# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
482# while the type of the variable "size" is referenced. The cursor
483# referenced by the type of size is the typedef for size_type.
484CursorKind.TYPE_REF = CursorKind(43)
485CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
486
487# A reference to a class template, function template, template
488# template parameter, or class template partial specialization.
489CursorKind.TEMPLATE_REF = CursorKind(45)
490
491# A reference to a namespace or namepsace alias.
492CursorKind.NAMESPACE_REF = CursorKind(46)
493
494# A reference to a member of a struct, union, or class that occurs in
495# some non-expression context, e.g., a designated initializer.
496CursorKind.MEMBER_REF = CursorKind(47)
497
498# A reference to a labeled statement.
499CursorKind.LABEL_REF = CursorKind(48)
500
501# A reference toa a set of overloaded functions or function templates
502# that has not yet been resolved to a specific function or function template.
503CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
504
505###
506# Invalid/Error Kinds
507
508CursorKind.INVALID_FILE = CursorKind(70)
509CursorKind.NO_DECL_FOUND = CursorKind(71)
510CursorKind.NOT_IMPLEMENTED = CursorKind(72)
511CursorKind.INVALID_CODE = CursorKind(73)
512
513###
514# Expression Kinds
515
516# An expression whose specific kind is not exposed via this interface.
517#
518# Unexposed expressions have the same operations as any other kind of
519# expression; one can extract their location information, spelling, children,
520# etc. However, the specific kind of the expression is not reported.
521CursorKind.UNEXPOSED_EXPR = CursorKind(100)
522
523# An expression that refers to some value declaration, such as a function,
524# varible, or enumerator.
525CursorKind.DECL_REF_EXPR = CursorKind(101)
526
527# An expression that refers to a member of a struct, union, class, Objective-C
528# class, etc.
529CursorKind.MEMBER_REF_EXPR = CursorKind(102)
530
531# An expression that calls a function.
532CursorKind.CALL_EXPR = CursorKind(103)
533
534# An expression that sends a message to an Objective-C object or class.
535CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
536
537# An expression that represents a block literal.
538CursorKind.BLOCK_EXPR = CursorKind(105)
539
540# An integer literal.
541CursorKind.INTEGER_LITERAL = CursorKind(106)
542
543# A floating point number literal.
544CursorKind.FLOATING_LITERAL = CursorKind(107)
545
546# An imaginary number literal.
547CursorKind.IMAGINARY_LITERAL = CursorKind(108)
548
549# A string literal.
550CursorKind.STRING_LITERAL = CursorKind(109)
551
552# A character literal.
553CursorKind.CHARACTER_LITERAL = CursorKind(110)
554
555# A parenthesized expression, e.g. "(1)".
556#
557# This AST node is only formed if full location information is requested.
558CursorKind.PAREN_EXPR = CursorKind(111)
559
560# This represents the unary-expression's (except sizeof and
561# alignof).
562CursorKind.UNARY_OPERATOR = CursorKind(112)
563
564# [C99 6.5.2.1] Array Subscripting.
565CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113)
566
567# A builtin binary operation expression such as "x + y" or
568# "x <= y".
569CursorKind.BINARY_OPERATOR = CursorKind(114)
570
571# Compound assignment such as "+=".
572CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115)
573
574# The ?: ternary operator.
575CursorKind.CONDITONAL_OPERATOR = CursorKind(116)
576
577# An explicit cast in C (C99 6.5.4) or a C-style cast in C++
578# (C++ [expr.cast]), which uses the syntax (Type)expr.
579#
580# For example: (int)f.
581CursorKind.CSTYLE_CAST_EXPR = CursorKind(117)
582
583# [C99 6.5.2.5]
584CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118)
585
586# Describes an C or C++ initializer list.
587CursorKind.INIT_LIST_EXPR = CursorKind(119)
588
589# The GNU address of label extension, representing &&label.
590CursorKind.ADDR_LABEL_EXPR = CursorKind(120)
591
592# This is the GNU Statement Expression extension: ({int X=4; X;})
593CursorKind.StmtExpr = CursorKind(121)
594
595# Represents a C1X generic selection.
596CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122)
597
598# Implements the GNU __null extension, which is a name for a null
599# pointer constant that has integral type (e.g., int or long) and is the same
600# size and alignment as a pointer.
601#
602# The __null extension is typically only used by system headers, which define
603# NULL as __null in C++ rather than using 0 (which is an integer that may not
604# match the size of a pointer).
605CursorKind.GNU_NULL_EXPR = CursorKind(123)
606
607# C++'s static_cast<> expression.
608CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124)
609
610# C++'s dynamic_cast<> expression.
611CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125)
612
613# C++'s reinterpret_cast<> expression.
614CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126)
615
616# C++'s const_cast<> expression.
617CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127)
618
619# Represents an explicit C++ type conversion that uses "functional"
620# notion (C++ [expr.type.conv]).
621#
622# Example:
623# \code
624#   x = int(0.5);
625# \endcode
626CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128)
627
628# A C++ typeid expression (C++ [expr.typeid]).
629CursorKind.CXX_TYPEID_EXPR = CursorKind(129)
630
631# [C++ 2.13.5] C++ Boolean Literal.
632CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130)
633
634# [C++0x 2.14.7] C++ Pointer Literal.
635CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131)
636
637# Represents the "this" expression in C++
638CursorKind.CXX_THIS_EXPR = CursorKind(132)
639
640# [C++ 15] C++ Throw Expression.
641#
642# This handles 'throw' and 'throw' assignment-expression. When
643# assignment-expression isn't present, Op will be null.
644CursorKind.CXX_THROW_EXPR = CursorKind(133)
645
646# A new expression for memory allocation and constructor calls, e.g:
647# "new CXXNewExpr(foo)".
648CursorKind.CXX_NEW_EXPR = CursorKind(134)
649
650# A delete expression for memory deallocation and destructor calls,
651# e.g. "delete[] pArray".
652CursorKind.CXX_DELETE_EXPR = CursorKind(135)
653
654# Represents a unary expression.
655CursorKind.CXX_UNARY_EXPR = CursorKind(136)
656
657# ObjCStringLiteral, used for Objective-C string literals i.e. "foo".
658CursorKind.OBJC_STRING_LITERAL = CursorKind(137)
659
660# ObjCEncodeExpr, used for in Objective-C.
661CursorKind.OBJC_ENCODE_EXPR = CursorKind(138)
662
663# ObjCSelectorExpr used for in Objective-C.
664CursorKind.OBJC_SELECTOR_EXPR = CursorKind(139)
665
666# Objective-C's protocol expression.
667CursorKind.OBJC_PROTOCOL_EXPR = CursorKind(140)
668
669# An Objective-C "bridged" cast expression, which casts between
670# Objective-C pointers and C pointers, transferring ownership in the process.
671#
672# \code
673#   NSString *str = (__bridge_transfer NSString *)CFCreateString();
674# \endcode
675CursorKind.OBJC_BRIDGE_CAST_EXPR = CursorKind(141)
676
677# Represents a C++0x pack expansion that produces a sequence of
678# expressions.
679#
680# A pack expansion expression contains a pattern (which itself is an
681# expression) followed by an ellipsis. For example:
682CursorKind.PACK_EXPANSION_EXPR = CursorKind(142)
683
684# Represents an expression that computes the length of a parameter
685# pack.
686CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143)
687
688# A statement whose specific kind is not exposed via this interface.
689#
690# Unexposed statements have the same operations as any other kind of statement;
691# one can extract their location information, spelling, children, etc. However,
692# the specific kind of the statement is not reported.
693CursorKind.UNEXPOSED_STMT = CursorKind(200)
694
695# A labelled statement in a function.
696CursorKind.LABEL_STMT = CursorKind(201)
697
698# A compound statement
699CursorKind.COMPOUND_STMT = CursorKind(202)
700
701# A case statement.
702CursorKind.CASE_STMT = CursorKind(203)
703
704# A default statement.
705CursorKind.DEFAULT_STMT = CursorKind(204)
706
707# An if statement.
708CursorKind.IF_STMT = CursorKind(205)
709
710# A switch statement.
711CursorKind.SWITCH_STMT = CursorKind(206)
712
713# A while statement.
714CursorKind.WHILE_STMT = CursorKind(207)
715
716# A do statement.
717CursorKind.DO_STMT = CursorKind(208)
718
719# A for statement.
720CursorKind.FOR_STMT = CursorKind(209)
721
722# A goto statement.
723CursorKind.GOTO_STMT = CursorKind(210)
724
725# An indirect goto statement.
726CursorKind.INDIRECT_GOTO_STMT = CursorKind(211)
727
728# A continue statement.
729CursorKind.CONTINUE_STMT = CursorKind(212)
730
731# A break statement.
732CursorKind.BREAK_STMT = CursorKind(213)
733
734# A return statement.
735CursorKind.RETURN_STMT = CursorKind(214)
736
737# A GNU-style inline assembler statement.
738CursorKind.ASM_STMT = CursorKind(215)
739
740# Objective-C's overall @try-@catch-@finally statement.
741CursorKind.OBJC_AT_TRY_STMT = CursorKind(216)
742
743# Objective-C's @catch statement.
744CursorKind.OBJC_AT_CATCH_STMT = CursorKind(217)
745
746# Objective-C's @finally statement.
747CursorKind.OBJC_AT_FINALLY_STMT = CursorKind(218)
748
749# Objective-C's @throw statement.
750CursorKind.OBJC_AT_THROW_STMT = CursorKind(219)
751
752# Objective-C's @synchronized statement.
753CursorKind.OBJC_AT_SYNCHRONIZED_STMT = CursorKind(220)
754
755# Objective-C's autorealease pool statement.
756CursorKind.OBJC_AUTORELEASE_POOL_STMT = CursorKind(221)
757
758# Objective-C's for collection statement.
759CursorKind.OBJC_FOR_COLLECTION_STMT = CursorKind(222)
760
761# C++'s catch statement.
762CursorKind.CXX_CATCH_STMT = CursorKind(223)
763
764# C++'s try statement.
765CursorKind.CXX_TRY_STMT = CursorKind(224)
766
767# C++'s for (* : *) statement.
768CursorKind.CXX_FOR_RANGE_STMT = CursorKind(225)
769
770# Windows Structured Exception Handling's try statement.
771CursorKind.SEH_TRY_STMT = CursorKind(226)
772
773# Windows Structured Exception Handling's except statement.
774CursorKind.SEH_EXCEPT_STMT = CursorKind(227)
775
776# Windows Structured Exception Handling's finally statement.
777CursorKind.SEH_FINALLY_STMT = CursorKind(228)
778
779# The null statement.
780CursorKind.NULL_STMT = CursorKind(230)
781
782# Adaptor class for mixing declarations with statements and expressions.
783CursorKind.DECL_STMT = CursorKind(231)
784
785###
786# Other Kinds
787
788# Cursor that represents the translation unit itself.
789#
790# The translation unit cursor exists primarily to act as the root cursor for
791# traversing the contents of a translation unit.
792CursorKind.TRANSLATION_UNIT = CursorKind(300)
793
794###
795# Attributes
796
797# An attribute whoe specific kind is note exposed via this interface
798CursorKind.UNEXPOSED_ATTR = CursorKind(400)
799
800CursorKind.IB_ACTION_ATTR = CursorKind(401)
801CursorKind.IB_OUTLET_ATTR = CursorKind(402)
802CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403)
803
804###
805# Preprocessing
806CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
807CursorKind.MACRO_DEFINITION = CursorKind(501)
808CursorKind.MACRO_INSTANTIATION = CursorKind(502)
809CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
810
811### Cursors ###
812
813class Cursor(Structure):
814    """
815    The Cursor class represents a reference to an element within the AST. It
816    acts as a kind of iterator.
817    """
818    _fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)]
819
820    def __eq__(self, other):
821        return Cursor_eq(self, other)
822
823    def __ne__(self, other):
824        return not Cursor_eq(self, other)
825
826    def is_definition(self):
827        """
828        Returns true if the declaration pointed at by the cursor is also a
829        definition of that entity.
830        """
831        return Cursor_is_def(self)
832
833    def get_definition(self):
834        """
835        If the cursor is a reference to a declaration or a declaration of
836        some entity, return a cursor that points to the definition of that
837        entity.
838        """
839        # TODO: Should probably check that this is either a reference or
840        # declaration prior to issuing the lookup.
841        return Cursor_def(self)
842
843    def get_usr(self):
844        """Return the Unified Symbol Resultion (USR) for the entity referenced
845        by the given cursor (or None).
846
847        A Unified Symbol Resolution (USR) is a string that identifies a
848        particular entity (function, class, variable, etc.) within a
849        program. USRs can be compared across translation units to determine,
850        e.g., when references in one translation refer to an entity defined in
851        another translation unit."""
852        return Cursor_usr(self)
853
854    @property
855    def kind(self):
856        """Return the kind of this cursor."""
857        return CursorKind.from_id(self._kind_id)
858
859    @property
860    def spelling(self):
861        """Return the spelling of the entity pointed at by the cursor."""
862        if not self.kind.is_declaration():
863            # FIXME: clang_getCursorSpelling should be fixed to not assert on
864            # this, for consistency with clang_getCursorUSR.
865            return None
866        if not hasattr(self, '_spelling'):
867            self._spelling = Cursor_spelling(self)
868        return self._spelling
869
870    @property
871    def displayname(self):
872        """
873        Return the display name for the entity referenced by this cursor.
874
875        The display name contains extra information that helps identify the cursor,
876        such as the parameters of a function or template or the arguments of a
877        class template specialization.
878        """
879        if not hasattr(self, '_displayname'):
880            self._displayname = Cursor_displayname(self)
881        return self._displayname
882
883    @property
884    def location(self):
885        """
886        Return the source location (the starting character) of the entity
887        pointed at by the cursor.
888        """
889        if not hasattr(self, '_loc'):
890            self._loc = Cursor_loc(self)
891        return self._loc
892
893    @property
894    def extent(self):
895        """
896        Return the source range (the range of text) occupied by the entity
897        pointed at by the cursor.
898        """
899        if not hasattr(self, '_extent'):
900            self._extent = Cursor_extent(self)
901        return self._extent
902
903    @property
904    def type(self):
905        """
906        Retrieve the type (if any) of of the entity pointed at by the
907        cursor.
908        """
909        if not hasattr(self, '_type'):
910            self._type = Cursor_type(self)
911        return self._type
912
913    def get_children(self):
914        """Return an iterator for accessing the children of this cursor."""
915
916        # FIXME: Expose iteration from CIndex, PR6125.
917        def visitor(child, parent, children):
918            # FIXME: Document this assertion in API.
919            # FIXME: There should just be an isNull method.
920            assert child != Cursor_null()
921            children.append(child)
922            return 1 # continue
923        children = []
924        Cursor_visit(self, Cursor_visit_callback(visitor), children)
925        return iter(children)
926
927    @staticmethod
928    def from_result(res, fn, args):
929        assert isinstance(res, Cursor)
930        # FIXME: There should just be an isNull method.
931        if res == Cursor_null():
932            return None
933        return res
934
935
936### Type Kinds ###
937
938class TypeKind(object):
939    """
940    Describes the kind of type.
941    """
942
943    # The unique kind objects, indexed by id.
944    _kinds = []
945    _name_map = None
946
947    def __init__(self, value):
948        if value >= len(TypeKind._kinds):
949            TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1)
950        if TypeKind._kinds[value] is not None:
951            raise ValueError,'TypeKind already loaded'
952        self.value = value
953        TypeKind._kinds[value] = self
954        TypeKind._name_map = None
955
956    def from_param(self):
957        return self.value
958
959    @property
960    def name(self):
961        """Get the enumeration name of this cursor kind."""
962        if self._name_map is None:
963            self._name_map = {}
964            for key,value in TypeKind.__dict__.items():
965                if isinstance(value,TypeKind):
966                    self._name_map[value] = key
967        return self._name_map[self]
968
969    @staticmethod
970    def from_id(id):
971        if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
972            raise ValueError,'Unknown type kind %d' % id
973        return TypeKind._kinds[id]
974
975    def __repr__(self):
976        return 'TypeKind.%s' % (self.name,)
977
978
979
980TypeKind.INVALID = TypeKind(0)
981TypeKind.UNEXPOSED = TypeKind(1)
982TypeKind.VOID = TypeKind(2)
983TypeKind.BOOL = TypeKind(3)
984TypeKind.CHAR_U = TypeKind(4)
985TypeKind.UCHAR = TypeKind(5)
986TypeKind.CHAR16 = TypeKind(6)
987TypeKind.CHAR32 = TypeKind(7)
988TypeKind.USHORT = TypeKind(8)
989TypeKind.UINT = TypeKind(9)
990TypeKind.ULONG = TypeKind(10)
991TypeKind.ULONGLONG = TypeKind(11)
992TypeKind.UINT128 = TypeKind(12)
993TypeKind.CHAR_S = TypeKind(13)
994TypeKind.SCHAR = TypeKind(14)
995TypeKind.WCHAR = TypeKind(15)
996TypeKind.SHORT = TypeKind(16)
997TypeKind.INT = TypeKind(17)
998TypeKind.LONG = TypeKind(18)
999TypeKind.LONGLONG = TypeKind(19)
1000TypeKind.INT128 = TypeKind(20)
1001TypeKind.FLOAT = TypeKind(21)
1002TypeKind.DOUBLE = TypeKind(22)
1003TypeKind.LONGDOUBLE = TypeKind(23)
1004TypeKind.NULLPTR = TypeKind(24)
1005TypeKind.OVERLOAD = TypeKind(25)
1006TypeKind.DEPENDENT = TypeKind(26)
1007TypeKind.OBJCID = TypeKind(27)
1008TypeKind.OBJCCLASS = TypeKind(28)
1009TypeKind.OBJCSEL = TypeKind(29)
1010TypeKind.COMPLEX = TypeKind(100)
1011TypeKind.POINTER = TypeKind(101)
1012TypeKind.BLOCKPOINTER = TypeKind(102)
1013TypeKind.LVALUEREFERENCE = TypeKind(103)
1014TypeKind.RVALUEREFERENCE = TypeKind(104)
1015TypeKind.RECORD = TypeKind(105)
1016TypeKind.ENUM = TypeKind(106)
1017TypeKind.TYPEDEF = TypeKind(107)
1018TypeKind.OBJCINTERFACE = TypeKind(108)
1019TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
1020TypeKind.FUNCTIONNOPROTO = TypeKind(110)
1021TypeKind.FUNCTIONPROTO = TypeKind(111)
1022
1023
1024class Type(Structure):
1025    """
1026    The type of an element in the abstract syntax tree.
1027    """
1028    _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
1029
1030    @property
1031    def kind(self):
1032        """Return the kind of this type."""
1033        return TypeKind.from_id(self._kind_id)
1034
1035    @staticmethod
1036    def from_result(res, fn, args):
1037        assert isinstance(res, Type)
1038        return res
1039
1040    def get_canonical(self):
1041        """
1042        Return the canonical type for a Type.
1043
1044        Clang's type system explicitly models typedefs and all the
1045        ways a specific type can be represented.  The canonical type
1046        is the underlying type with all the "sugar" removed.  For
1047        example, if 'T' is a typedef for 'int', the canonical type for
1048        'T' would be 'int'.
1049        """
1050        return Type_get_canonical(self)
1051
1052    def is_const_qualified(self):
1053        """
1054        Determine whether a Type has the "const" qualifier set,
1055        without looking through typedefs that may have added "const"
1056        at a different level.
1057        """
1058        return Type_is_const_qualified(self)
1059
1060    def is_volatile_qualified(self):
1061        """
1062        Determine whether a Type has the "volatile" qualifier set,
1063        without looking through typedefs that may have added
1064        "volatile" at a different level.
1065        """
1066        return Type_is_volatile_qualified(self)
1067
1068    def is_restrict_qualified(self):
1069        """
1070        Determine whether a Type has the "restrict" qualifier set,
1071        without looking through typedefs that may have added
1072        "restrict" at a different level.
1073        """
1074        return Type_is_restrict_qualified(self)
1075
1076    def get_pointee(self):
1077        """
1078        For pointer types, returns the type of the pointee.
1079        """
1080        return Type_get_pointee(self)
1081
1082    def get_declaration(self):
1083        """
1084        Return the cursor for the declaration of the given type.
1085        """
1086        return Type_get_declaration(self)
1087
1088    def get_result(self):
1089        """
1090        Retrieve the result type associated with a function type.
1091        """
1092        return Type_get_result(self)
1093
1094## CIndex Objects ##
1095
1096# CIndex objects (derived from ClangObject) are essentially lightweight
1097# wrappers attached to some underlying object, which is exposed via CIndex as
1098# a void*.
1099
1100class ClangObject(object):
1101    """
1102    A helper for Clang objects. This class helps act as an intermediary for
1103    the ctypes library and the Clang CIndex library.
1104    """
1105    def __init__(self, obj):
1106        assert isinstance(obj, c_object_p) and obj
1107        self.obj = self._as_parameter_ = obj
1108
1109    def from_param(self):
1110        return self._as_parameter_
1111
1112
1113class _CXUnsavedFile(Structure):
1114    """Helper for passing unsaved file arguments."""
1115    _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
1116
1117## Diagnostic Conversion ##
1118
1119_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
1120_clang_getNumDiagnostics.argtypes = [c_object_p]
1121_clang_getNumDiagnostics.restype = c_uint
1122
1123_clang_getDiagnostic = lib.clang_getDiagnostic
1124_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
1125_clang_getDiagnostic.restype = c_object_p
1126
1127_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
1128_clang_disposeDiagnostic.argtypes = [Diagnostic]
1129
1130_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
1131_clang_getDiagnosticSeverity.argtypes = [Diagnostic]
1132_clang_getDiagnosticSeverity.restype = c_int
1133
1134_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
1135_clang_getDiagnosticLocation.argtypes = [Diagnostic]
1136_clang_getDiagnosticLocation.restype = SourceLocation
1137
1138_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
1139_clang_getDiagnosticSpelling.argtypes = [Diagnostic]
1140_clang_getDiagnosticSpelling.restype = _CXString
1141_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
1142
1143_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
1144_clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
1145_clang_getDiagnosticNumRanges.restype = c_uint
1146
1147_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
1148_clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
1149_clang_getDiagnosticRange.restype = SourceRange
1150
1151_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
1152_clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
1153_clang_getDiagnosticNumFixIts.restype = c_uint
1154
1155_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
1156_clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)]
1157_clang_getDiagnosticFixIt.restype = _CXString
1158_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
1159
1160###
1161
1162class CompletionChunk:
1163    class Kind:
1164        def __init__(self, name):
1165            self.name = name
1166
1167        def __str__(self):
1168            return self.name
1169
1170        def __repr__(self):
1171            return "<ChunkKind: %s>" % self
1172
1173    def __init__(self, completionString, key):
1174        self.cs = completionString
1175        self.key = key
1176
1177    def __repr__(self):
1178        return "{'" + self.spelling + "', " + str(self.kind) + "}"
1179
1180    @property
1181    def spelling(self):
1182        return _clang_getCompletionChunkText(self.cs, self.key).spelling
1183
1184    @property
1185    def kind(self):
1186        res = _clang_getCompletionChunkKind(self.cs, self.key)
1187        return completionChunkKindMap[res]
1188
1189    @property
1190    def string(self):
1191        res = _clang_getCompletionChunkCompletionString(self.cs, self.key)
1192
1193        if (res):
1194          return CompletionString(res)
1195        else:
1196          None
1197
1198    def isKindOptional(self):
1199      return self.kind == completionChunkKindMap[0]
1200
1201    def isKindTypedText(self):
1202      return self.kind == completionChunkKindMap[1]
1203
1204    def isKindPlaceHolder(self):
1205      return self.kind == completionChunkKindMap[3]
1206
1207    def isKindInformative(self):
1208      return self.kind == completionChunkKindMap[4]
1209
1210    def isKindResultType(self):
1211      return self.kind == completionChunkKindMap[15]
1212
1213completionChunkKindMap = {
1214            0: CompletionChunk.Kind("Optional"),
1215            1: CompletionChunk.Kind("TypedText"),
1216            2: CompletionChunk.Kind("Text"),
1217            3: CompletionChunk.Kind("Placeholder"),
1218            4: CompletionChunk.Kind("Informative"),
1219            5: CompletionChunk.Kind("CurrentParameter"),
1220            6: CompletionChunk.Kind("LeftParen"),
1221            7: CompletionChunk.Kind("RightParen"),
1222            8: CompletionChunk.Kind("LeftBracket"),
1223            9: CompletionChunk.Kind("RightBracket"),
1224            10: CompletionChunk.Kind("LeftBrace"),
1225            11: CompletionChunk.Kind("RightBrace"),
1226            12: CompletionChunk.Kind("LeftAngle"),
1227            13: CompletionChunk.Kind("RightAngle"),
1228            14: CompletionChunk.Kind("Comma"),
1229            15: CompletionChunk.Kind("ResultType"),
1230            16: CompletionChunk.Kind("Colon"),
1231            17: CompletionChunk.Kind("SemiColon"),
1232            18: CompletionChunk.Kind("Equal"),
1233            19: CompletionChunk.Kind("HorizontalSpace"),
1234            20: CompletionChunk.Kind("VerticalSpace")}
1235
1236class CompletionString(ClangObject):
1237    class Availability:
1238        def __init__(self, name):
1239            self.name = name
1240
1241        def __str__(self):
1242            return self.name
1243
1244        def __repr__(self):
1245            return "<Availability: %s>" % self
1246
1247    def __len__(self):
1248        return _clang_getNumCompletionChunks(self.obj)
1249
1250    def __getitem__(self, key):
1251        if len(self) <= key:
1252            raise IndexError
1253        return CompletionChunk(self.obj, key)
1254
1255    @property
1256    def priority(self):
1257        return _clang_getCompletionPriority(self.obj)
1258
1259    @property
1260    def availability(self):
1261        res = _clang_getCompletionAvailability(self.obj)
1262        return availabilityKinds[res]
1263
1264    def __repr__(self):
1265        return " | ".join([str(a) for a in self]) \
1266               + " || Priority: " + str(self.priority) \
1267               + " || Availability: " + str(self.availability)
1268
1269availabilityKinds = {
1270            0: CompletionChunk.Kind("Available"),
1271            1: CompletionChunk.Kind("Deprecated"),
1272            2: CompletionChunk.Kind("NotAvailable")}
1273
1274class CodeCompletionResult(Structure):
1275    _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
1276
1277    def __repr__(self):
1278        return str(CompletionString(self.completionString))
1279
1280    @property
1281    def kind(self):
1282        return CursorKind.from_id(self.cursorKind)
1283
1284    @property
1285    def string(self):
1286        return CompletionString(self.completionString)
1287
1288class CCRStructure(Structure):
1289    _fields_ = [('results', POINTER(CodeCompletionResult)),
1290                ('numResults', c_int)]
1291
1292    def __len__(self):
1293        return self.numResults
1294
1295    def __getitem__(self, key):
1296        if len(self) <= key:
1297            raise IndexError
1298
1299        return self.results[key]
1300
1301class CodeCompletionResults(ClangObject):
1302    def __init__(self, ptr):
1303        assert isinstance(ptr, POINTER(CCRStructure)) and ptr
1304        self.ptr = self._as_parameter_ = ptr
1305
1306    def from_param(self):
1307        return self._as_parameter_
1308
1309    def __del__(self):
1310        CodeCompletionResults_dispose(self)
1311
1312    @property
1313    def results(self):
1314        return self.ptr.contents
1315
1316    @property
1317    def diagnostics(self):
1318        class DiagnosticsItr:
1319            def __init__(self, ccr):
1320                self.ccr= ccr
1321
1322            def __len__(self):
1323                return int(_clang_codeCompleteGetNumDiagnostics(self.ccr))
1324
1325            def __getitem__(self, key):
1326                return _clang_codeCompleteGetDiagnostic(self.ccr, key)
1327
1328        return DiagnosticsItr(self)
1329
1330
1331class Index(ClangObject):
1332    """
1333    The Index type provides the primary interface to the Clang CIndex library,
1334    primarily by providing an interface for reading and parsing translation
1335    units.
1336    """
1337
1338    @staticmethod
1339    def create(excludeDecls=False):
1340        """
1341        Create a new Index.
1342        Parameters:
1343        excludeDecls -- Exclude local declarations from translation units.
1344        """
1345        return Index(Index_create(excludeDecls, 0))
1346
1347    def __del__(self):
1348        Index_dispose(self)
1349
1350    def read(self, path):
1351        """Load the translation unit from the given AST file."""
1352        ptr = TranslationUnit_read(self, path)
1353        return TranslationUnit(ptr) if ptr else None
1354
1355    def parse(self, path, args = [], unsaved_files = [], options = 0):
1356        """
1357        Load the translation unit from the given source code file by running
1358        clang and generating the AST before loading. Additional command line
1359        parameters can be passed to clang via the args parameter.
1360
1361        In-memory contents for files can be provided by passing a list of pairs
1362        to as unsaved_files, the first item should be the filenames to be mapped
1363        and the second should be the contents to be substituted for the
1364        file. The contents may be passed as strings or file objects.
1365        """
1366        arg_array = 0
1367        if len(args):
1368            arg_array = (c_char_p * len(args))(* args)
1369        unsaved_files_array = 0
1370        if len(unsaved_files):
1371            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1372            for i,(name,value) in enumerate(unsaved_files):
1373                if not isinstance(value, str):
1374                    # FIXME: It would be great to support an efficient version
1375                    # of this, one day.
1376                    value = value.read()
1377                    print value
1378                if not isinstance(value, str):
1379                    raise TypeError,'Unexpected unsaved file contents.'
1380                unsaved_files_array[i].name = name
1381                unsaved_files_array[i].contents = value
1382                unsaved_files_array[i].length = len(value)
1383        ptr = TranslationUnit_parse(self, path, arg_array, len(args),
1384                                    unsaved_files_array, len(unsaved_files),
1385                                    options)
1386        return TranslationUnit(ptr) if ptr else None
1387
1388
1389class TranslationUnit(ClangObject):
1390    """
1391    The TranslationUnit class represents a source code translation unit and
1392    provides read-only access to its top-level declarations.
1393    """
1394
1395    def __init__(self, ptr):
1396        ClangObject.__init__(self, ptr)
1397
1398    def __del__(self):
1399        TranslationUnit_dispose(self)
1400
1401    @property
1402    def cursor(self):
1403        """Retrieve the cursor that represents the given translation unit."""
1404        return TranslationUnit_cursor(self)
1405
1406    @property
1407    def spelling(self):
1408        """Get the original translation unit source file name."""
1409        return TranslationUnit_spelling(self)
1410
1411    def get_includes(self):
1412        """
1413        Return an iterable sequence of FileInclusion objects that describe the
1414        sequence of inclusions in a translation unit. The first object in
1415        this sequence is always the input file. Note that this method will not
1416        recursively iterate over header files included through precompiled
1417        headers.
1418        """
1419        def visitor(fobj, lptr, depth, includes):
1420            if depth > 0:
1421                loc = lptr.contents
1422                includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
1423
1424        # Automatically adapt CIndex/ctype pointers to python objects
1425        includes = []
1426        TranslationUnit_includes(self,
1427                                 TranslationUnit_includes_callback(visitor),
1428                                 includes)
1429        return iter(includes)
1430
1431    @property
1432    def diagnostics(self):
1433        """
1434        Return an iterable (and indexable) object containing the diagnostics.
1435        """
1436        class DiagIterator:
1437            def __init__(self, tu):
1438                self.tu = tu
1439
1440            def __len__(self):
1441                return int(_clang_getNumDiagnostics(self.tu))
1442
1443            def __getitem__(self, key):
1444                diag = _clang_getDiagnostic(self.tu, key)
1445                if not diag:
1446                    raise IndexError
1447                return Diagnostic(diag)
1448
1449        return DiagIterator(self)
1450
1451    def reparse(self, unsaved_files = [], options = 0):
1452        """
1453        Reparse an already parsed translation unit.
1454
1455        In-memory contents for files can be provided by passing a list of pairs
1456        as unsaved_files, the first items should be the filenames to be mapped
1457        and the second should be the contents to be substituted for the
1458        file. The contents may be passed as strings or file objects.
1459        """
1460        unsaved_files_array = 0
1461        if len(unsaved_files):
1462            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1463            for i,(name,value) in enumerate(unsaved_files):
1464                if not isinstance(value, str):
1465                    # FIXME: It would be great to support an efficient version
1466                    # of this, one day.
1467                    value = value.read()
1468                    print value
1469                if not isinstance(value, str):
1470                    raise TypeError,'Unexpected unsaved file contents.'
1471                unsaved_files_array[i].name = name
1472                unsaved_files_array[i].contents = value
1473                unsaved_files_array[i].length = len(value)
1474        ptr = TranslationUnit_reparse(self, len(unsaved_files),
1475                                      unsaved_files_array,
1476                                      options)
1477    def codeComplete(self, path, line, column, unsaved_files = [], options = 0):
1478        """
1479        Code complete in this translation unit.
1480
1481        In-memory contents for files can be provided by passing a list of pairs
1482        as unsaved_files, the first items should be the filenames to be mapped
1483        and the second should be the contents to be substituted for the
1484        file. The contents may be passed as strings or file objects.
1485        """
1486        unsaved_files_array = 0
1487        if len(unsaved_files):
1488            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1489            for i,(name,value) in enumerate(unsaved_files):
1490                if not isinstance(value, str):
1491                    # FIXME: It would be great to support an efficient version
1492                    # of this, one day.
1493                    value = value.read()
1494                    print value
1495                if not isinstance(value, str):
1496                    raise TypeError,'Unexpected unsaved file contents.'
1497                unsaved_files_array[i].name = name
1498                unsaved_files_array[i].contents = value
1499                unsaved_files_array[i].length = len(value)
1500        ptr = TranslationUnit_codeComplete(self, path,
1501                                           line, column,
1502                                           unsaved_files_array,
1503                                           len(unsaved_files),
1504                                           options)
1505        return CodeCompletionResults(ptr) if ptr else None
1506
1507
1508class File(ClangObject):
1509    """
1510    The File class represents a particular source file that is part of a
1511    translation unit.
1512    """
1513
1514    @property
1515    def name(self):
1516        """Return the complete file and path name of the file."""
1517        return _CXString_getCString(File_name(self))
1518
1519    @property
1520    def time(self):
1521        """Return the last modification time of the file."""
1522        return File_time(self)
1523
1524class FileInclusion(object):
1525    """
1526    The FileInclusion class represents the inclusion of one source file by
1527    another via a '#include' directive or as the input file for the translation
1528    unit. This class provides information about the included file, the including
1529    file, the location of the '#include' directive and the depth of the included
1530    file in the stack. Note that the input file has depth 0.
1531    """
1532
1533    def __init__(self, src, tgt, loc, depth):
1534        self.source = src
1535        self.include = tgt
1536        self.location = loc
1537        self.depth = depth
1538
1539    @property
1540    def is_input_file(self):
1541        """True if the included file is the input file."""
1542        return self.depth == 0
1543
1544# Additional Functions and Types
1545
1546# String Functions
1547_CXString_dispose = lib.clang_disposeString
1548_CXString_dispose.argtypes = [_CXString]
1549
1550_CXString_getCString = lib.clang_getCString
1551_CXString_getCString.argtypes = [_CXString]
1552_CXString_getCString.restype = c_char_p
1553
1554# Source Location Functions
1555SourceLocation_loc = lib.clang_getInstantiationLocation
1556SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
1557                               POINTER(c_uint), POINTER(c_uint),
1558                               POINTER(c_uint)]
1559
1560# Source Range Functions
1561SourceRange_getRange = lib.clang_getRange
1562SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
1563SourceRange_getRange.restype = SourceRange
1564
1565SourceRange_start = lib.clang_getRangeStart
1566SourceRange_start.argtypes = [SourceRange]
1567SourceRange_start.restype = SourceLocation
1568
1569SourceRange_end = lib.clang_getRangeEnd
1570SourceRange_end.argtypes = [SourceRange]
1571SourceRange_end.restype = SourceLocation
1572
1573# CursorKind Functions
1574CursorKind_is_decl = lib.clang_isDeclaration
1575CursorKind_is_decl.argtypes = [CursorKind]
1576CursorKind_is_decl.restype = bool
1577
1578CursorKind_is_ref = lib.clang_isReference
1579CursorKind_is_ref.argtypes = [CursorKind]
1580CursorKind_is_ref.restype = bool
1581
1582CursorKind_is_expr = lib.clang_isExpression
1583CursorKind_is_expr.argtypes = [CursorKind]
1584CursorKind_is_expr.restype = bool
1585
1586CursorKind_is_stmt = lib.clang_isStatement
1587CursorKind_is_stmt.argtypes = [CursorKind]
1588CursorKind_is_stmt.restype = bool
1589
1590CursorKind_is_attribute = lib.clang_isAttribute
1591CursorKind_is_attribute.argtypes = [CursorKind]
1592CursorKind_is_attribute.restype = bool
1593
1594CursorKind_is_inv = lib.clang_isInvalid
1595CursorKind_is_inv.argtypes = [CursorKind]
1596CursorKind_is_inv.restype = bool
1597
1598# Cursor Functions
1599# TODO: Implement this function
1600Cursor_get = lib.clang_getCursor
1601Cursor_get.argtypes = [TranslationUnit, SourceLocation]
1602Cursor_get.restype = Cursor
1603
1604Cursor_null = lib.clang_getNullCursor
1605Cursor_null.restype = Cursor
1606
1607Cursor_usr = lib.clang_getCursorUSR
1608Cursor_usr.argtypes = [Cursor]
1609Cursor_usr.restype = _CXString
1610Cursor_usr.errcheck = _CXString.from_result
1611
1612Cursor_is_def = lib.clang_isCursorDefinition
1613Cursor_is_def.argtypes = [Cursor]
1614Cursor_is_def.restype = bool
1615
1616Cursor_def = lib.clang_getCursorDefinition
1617Cursor_def.argtypes = [Cursor]
1618Cursor_def.restype = Cursor
1619Cursor_def.errcheck = Cursor.from_result
1620
1621Cursor_eq = lib.clang_equalCursors
1622Cursor_eq.argtypes = [Cursor, Cursor]
1623Cursor_eq.restype = c_uint
1624
1625Cursor_spelling = lib.clang_getCursorSpelling
1626Cursor_spelling.argtypes = [Cursor]
1627Cursor_spelling.restype = _CXString
1628Cursor_spelling.errcheck = _CXString.from_result
1629
1630Cursor_displayname = lib.clang_getCursorDisplayName
1631Cursor_displayname.argtypes = [Cursor]
1632Cursor_displayname.restype = _CXString
1633Cursor_displayname.errcheck = _CXString.from_result
1634
1635Cursor_loc = lib.clang_getCursorLocation
1636Cursor_loc.argtypes = [Cursor]
1637Cursor_loc.restype = SourceLocation
1638
1639Cursor_extent = lib.clang_getCursorExtent
1640Cursor_extent.argtypes = [Cursor]
1641Cursor_extent.restype = SourceRange
1642
1643Cursor_ref = lib.clang_getCursorReferenced
1644Cursor_ref.argtypes = [Cursor]
1645Cursor_ref.restype = Cursor
1646Cursor_ref.errcheck = Cursor.from_result
1647
1648Cursor_type = lib.clang_getCursorType
1649Cursor_type.argtypes = [Cursor]
1650Cursor_type.restype = Type
1651Cursor_type.errcheck = Type.from_result
1652
1653Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
1654Cursor_visit = lib.clang_visitChildren
1655Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
1656Cursor_visit.restype = c_uint
1657
1658# Type Functions
1659Type_get_canonical = lib.clang_getCanonicalType
1660Type_get_canonical.argtypes = [Type]
1661Type_get_canonical.restype = Type
1662Type_get_canonical.errcheck = Type.from_result
1663
1664Type_is_const_qualified = lib.clang_isConstQualifiedType
1665Type_is_const_qualified.argtypes = [Type]
1666Type_is_const_qualified.restype = bool
1667
1668Type_is_volatile_qualified = lib.clang_isVolatileQualifiedType
1669Type_is_volatile_qualified.argtypes = [Type]
1670Type_is_volatile_qualified.restype = bool
1671
1672Type_is_restrict_qualified = lib.clang_isRestrictQualifiedType
1673Type_is_restrict_qualified.argtypes = [Type]
1674Type_is_restrict_qualified.restype = bool
1675
1676Type_get_pointee = lib.clang_getPointeeType
1677Type_get_pointee.argtypes = [Type]
1678Type_get_pointee.restype = Type
1679Type_get_pointee.errcheck = Type.from_result
1680
1681Type_get_declaration = lib.clang_getTypeDeclaration
1682Type_get_declaration.argtypes = [Type]
1683Type_get_declaration.restype = Cursor
1684Type_get_declaration.errcheck = Cursor.from_result
1685
1686Type_get_result = lib.clang_getResultType
1687Type_get_result.argtypes = [Type]
1688Type_get_result.restype = Type
1689Type_get_result.errcheck = Type.from_result
1690
1691
1692# Index Functions
1693Index_create = lib.clang_createIndex
1694Index_create.argtypes = [c_int, c_int]
1695Index_create.restype = c_object_p
1696
1697Index_dispose = lib.clang_disposeIndex
1698Index_dispose.argtypes = [Index]
1699
1700# Translation Unit Functions
1701TranslationUnit_read = lib.clang_createTranslationUnit
1702TranslationUnit_read.argtypes = [Index, c_char_p]
1703TranslationUnit_read.restype = c_object_p
1704
1705TranslationUnit_parse = lib.clang_parseTranslationUnit
1706TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p,
1707                                  c_int, c_void_p, c_int, c_int]
1708TranslationUnit_parse.restype = c_object_p
1709
1710TranslationUnit_reparse = lib.clang_reparseTranslationUnit
1711TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int]
1712TranslationUnit_reparse.restype = c_int
1713
1714TranslationUnit_codeComplete = lib.clang_codeCompleteAt
1715TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int,
1716                                         c_int, c_void_p, c_int, c_int]
1717TranslationUnit_codeComplete.restype = POINTER(CCRStructure)
1718
1719TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
1720TranslationUnit_cursor.argtypes = [TranslationUnit]
1721TranslationUnit_cursor.restype = Cursor
1722TranslationUnit_cursor.errcheck = Cursor.from_result
1723
1724TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
1725TranslationUnit_spelling.argtypes = [TranslationUnit]
1726TranslationUnit_spelling.restype = _CXString
1727TranslationUnit_spelling.errcheck = _CXString.from_result
1728
1729TranslationUnit_dispose = lib.clang_disposeTranslationUnit
1730TranslationUnit_dispose.argtypes = [TranslationUnit]
1731
1732TranslationUnit_includes_callback = CFUNCTYPE(None,
1733                                              c_object_p,
1734                                              POINTER(SourceLocation),
1735                                              c_uint, py_object)
1736TranslationUnit_includes = lib.clang_getInclusions
1737TranslationUnit_includes.argtypes = [TranslationUnit,
1738                                     TranslationUnit_includes_callback,
1739                                     py_object]
1740
1741# File Functions
1742File_name = lib.clang_getFileName
1743File_name.argtypes = [File]
1744File_name.restype = _CXString
1745
1746File_time = lib.clang_getFileTime
1747File_time.argtypes = [File]
1748File_time.restype = c_uint
1749
1750# Code completion
1751
1752CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults
1753CodeCompletionResults_dispose.argtypes = [CodeCompletionResults]
1754
1755_clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics
1756_clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
1757_clang_codeCompleteGetNumDiagnostics.restype = c_int
1758
1759_clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic
1760_clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int]
1761_clang_codeCompleteGetDiagnostic.restype = Diagnostic
1762
1763_clang_getCompletionChunkText = lib.clang_getCompletionChunkText
1764_clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
1765_clang_getCompletionChunkText.restype = _CXString
1766
1767_clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind
1768_clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
1769_clang_getCompletionChunkKind.restype = c_int
1770
1771_clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString
1772_clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
1773_clang_getCompletionChunkCompletionString.restype = c_object_p
1774
1775_clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks
1776_clang_getNumCompletionChunks.argtypes = [c_void_p]
1777_clang_getNumCompletionChunks.restype = c_int
1778
1779_clang_getCompletionAvailability = lib.clang_getCompletionAvailability
1780_clang_getCompletionAvailability.argtypes = [c_void_p]
1781_clang_getCompletionAvailability.restype = c_int
1782
1783_clang_getCompletionPriority = lib.clang_getCompletionPriority
1784_clang_getCompletionPriority.argtypes = [c_void_p]
1785_clang_getCompletionPriority.restype = c_int
1786
1787
1788###
1789
1790__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', 'Type', 'TypeKind',
1791           'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange',
1792           'SourceLocation', 'File']
1793