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 10 r""" 11 Clang Indexing Library Bindings 12 =============================== 13 14 This module provides an interface to the Clang indexing library. It is a 15 low-level interface to the indexing library which attempts to match the Clang 16 API directly while also being "pythonic". Notable differences from the C API 17 are: 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 25 The 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 44 Most object information is exposed using properties, when the underlying API 45 call 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 65 from ctypes import * 66 67 def 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**. 84 c_object_p = POINTER(c_void_p) 85 86 lib = get_cindex_library() 87 88 ### Structures and Utility Classes ### 89 90 class _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 103 class 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(c.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 142 class 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 177 class 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 250 class 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 266 class 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. 349 CursorKind.UNEXPOSED_DECL = CursorKind(1) 350 351 # A C or C++ struct. 352 CursorKind.STRUCT_DECL = CursorKind(2) 353 354 # A C or C++ union. 355 CursorKind.UNION_DECL = CursorKind(3) 356 357 # A C++ class. 358 CursorKind.CLASS_DECL = CursorKind(4) 359 360 # An enumeration. 361 CursorKind.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. 365 CursorKind.FIELD_DECL = CursorKind(6) 366 367 # An enumerator constant. 368 CursorKind.ENUM_CONSTANT_DECL = CursorKind(7) 369 370 # A function. 371 CursorKind.FUNCTION_DECL = CursorKind(8) 372 373 # A variable. 374 CursorKind.VAR_DECL = CursorKind(9) 375 376 # A function or method parameter. 377 CursorKind.PARM_DECL = CursorKind(10) 378 379 # An Objective-C @interface. 380 CursorKind.OBJC_INTERFACE_DECL = CursorKind(11) 381 382 # An Objective-C @interface for a category. 383 CursorKind.OBJC_CATEGORY_DECL = CursorKind(12) 384 385 # An Objective-C @protocol declaration. 386 CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13) 387 388 # An Objective-C @property declaration. 389 CursorKind.OBJC_PROPERTY_DECL = CursorKind(14) 390 391 # An Objective-C instance variable. 392 CursorKind.OBJC_IVAR_DECL = CursorKind(15) 393 394 # An Objective-C instance method. 395 CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16) 396 397 # An Objective-C class method. 398 CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17) 399 400 # An Objective-C @implementation. 401 CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18) 402 403 # An Objective-C @implementation for a category. 404 CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19) 405 406 # A typedef. 407 CursorKind.TYPEDEF_DECL = CursorKind(20) 408 409 # A C++ class method. 410 CursorKind.CXX_METHOD = CursorKind(21) 411 412 # A C++ namespace. 413 CursorKind.NAMESPACE = CursorKind(22) 414 415 # A linkage specification, e.g. 'extern "C"'. 416 CursorKind.LINKAGE_SPEC = CursorKind(23) 417 418 # A C++ constructor. 419 CursorKind.CONSTRUCTOR = CursorKind(24) 420 421 # A C++ destructor. 422 CursorKind.DESTRUCTOR = CursorKind(25) 423 424 # A C++ conversion function. 425 CursorKind.CONVERSION_FUNCTION = CursorKind(26) 426 427 # A C++ template type parameter 428 CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27) 429 430 # A C++ non-type template paramater. 431 CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28) 432 433 # A C++ template template parameter. 434 CursorKind.TEMPLATE_TEMPLATE_PARAMTER = CursorKind(29) 435 436 # A C++ function template. 437 CursorKind.FUNCTION_TEMPLATE = CursorKind(30) 438 439 # A C++ class template. 440 CursorKind.CLASS_TEMPLATE = CursorKind(31) 441 442 # A C++ class template partial specialization. 443 CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32) 444 445 # A C++ namespace alias declaration. 446 CursorKind.NAMESPACE_ALIAS = CursorKind(33) 447 448 # A C++ using directive 449 CursorKind.USING_DIRECTIVE = CursorKind(34) 450 451 # A C++ using declaration 452 CursorKind.USING_DECLARATION = CursorKind(35) 453 454 ### 455 # Reference Kinds 456 457 CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40) 458 CursorKind.OBJC_PROTOCOL_REF = CursorKind(41) 459 CursorKind.OBJC_CLASS_REF = CursorKind(42) 460 461 # A reference to a type declaration. 462 # 463 # A type reference occurs anywhere where a type is named but not 464 # declared. For example, given: 465 # typedef unsigned size_type; 466 # size_type size; 467 # 468 # The typedef is a declaration of size_type (CXCursor_TypedefDecl), 469 # while the type of the variable "size" is referenced. The cursor 470 # referenced by the type of size is the typedef for size_type. 471 CursorKind.TYPE_REF = CursorKind(43) 472 CursorKind.CXX_BASE_SPECIFIER = CursorKind(44) 473 474 # A reference to a class template, function template, template 475 # template parameter, or class template partial specialization. 476 CursorKind.TEMPLATE_REF = CursorKind(45) 477 478 # A reference to a namespace or namepsace alias. 479 CursorKind.NAMESPACE_REF = CursorKind(46) 480 481 # A reference to a member of a struct, union, or class that occurs in 482 # some non-expression context, e.g., a designated initializer. 483 CursorKind.MEMBER_REF = CursorKind(47) 484 485 # A reference to a labeled statement. 486 CursorKind.LABEL_REF = CursorKind(48) 487 488 # A reference toa a set of overloaded functions or function templates 489 # that has not yet been resolved to a specific function or function template. 490 CursorKind.OVERLOADED_DECL_REF = CursorKind(49) 491 492 ### 493 # Invalid/Error Kinds 494 495 CursorKind.INVALID_FILE = CursorKind(70) 496 CursorKind.NO_DECL_FOUND = CursorKind(71) 497 CursorKind.NOT_IMPLEMENTED = CursorKind(72) 498 CursorKind.INVALID_CODE = CursorKind(73) 499 500 ### 501 # Expression Kinds 502 503 # An expression whose specific kind is not exposed via this interface. 504 # 505 # Unexposed expressions have the same operations as any other kind of 506 # expression; one can extract their location information, spelling, children, 507 # etc. However, the specific kind of the expression is not reported. 508 CursorKind.UNEXPOSED_EXPR = CursorKind(100) 509 510 # An expression that refers to some value declaration, such as a function, 511 # varible, or enumerator. 512 CursorKind.DECL_REF_EXPR = CursorKind(101) 513 514 # An expression that refers to a member of a struct, union, class, Objective-C 515 # class, etc. 516 CursorKind.MEMBER_REF_EXPR = CursorKind(102) 517 518 # An expression that calls a function. 519 CursorKind.CALL_EXPR = CursorKind(103) 520 521 # An expression that sends a message to an Objective-C object or class. 522 CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104) 523 524 # An expression that represents a block literal. 525 CursorKind.BLOCK_EXPR = CursorKind(105) 526 527 # A statement whose specific kind is not exposed via this interface. 528 # 529 # Unexposed statements have the same operations as any other kind of statement; 530 # one can extract their location information, spelling, children, etc. However, 531 # the specific kind of the statement is not reported. 532 CursorKind.UNEXPOSED_STMT = CursorKind(200) 533 534 # A labelled statement in a function. 535 CursorKind.LABEL_STMT = CursorKind(201) 536 537 538 ### 539 # Other Kinds 540 541 # Cursor that represents the translation unit itself. 542 # 543 # The translation unit cursor exists primarily to act as the root cursor for 544 # traversing the contents of a translation unit. 545 CursorKind.TRANSLATION_UNIT = CursorKind(300) 546 547 ### 548 # Attributes 549 550 # An attribute whoe specific kind is note exposed via this interface 551 CursorKind.UNEXPOSED_ATTR = CursorKind(400) 552 553 CursorKind.IB_ACTION_ATTR = CursorKind(401) 554 CursorKind.IB_OUTLET_ATTR = CursorKind(402) 555 CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403) 556 557 ### 558 # Preprocessing 559 CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500) 560 CursorKind.MACRO_DEFINITION = CursorKind(501) 561 CursorKind.MACRO_INSTANTIATION = CursorKind(502) 562 CursorKind.INCLUSION_DIRECTIVE = CursorKind(503) 563 564 ### Cursors ### 565 566 class Cursor(Structure): 567 """ 568 The Cursor class represents a reference to an element within the AST. It 569 acts as a kind of iterator. 570 """ 571 _fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)] 572 573 def __eq__(self, other): 574 return Cursor_eq(self, other) 575 576 def __ne__(self, other): 577 return not Cursor_eq(self, other) 578 579 def is_definition(self): 580 """ 581 Returns true if the declaration pointed at by the cursor is also a 582 definition of that entity. 583 """ 584 return Cursor_is_def(self) 585 586 def get_definition(self): 587 """ 588 If the cursor is a reference to a declaration or a declaration of 589 some entity, return a cursor that points to the definition of that 590 entity. 591 """ 592 # TODO: Should probably check that this is either a reference or 593 # declaration prior to issuing the lookup. 594 return Cursor_def(self) 595 596 def get_usr(self): 597 """Return the Unified Symbol Resultion (USR) for the entity referenced 598 by the given cursor (or None). 599 600 A Unified Symbol Resolution (USR) is a string that identifies a 601 particular entity (function, class, variable, etc.) within a 602 program. USRs can be compared across translation units to determine, 603 e.g., when references in one translation refer to an entity defined in 604 another translation unit.""" 605 return Cursor_usr(self) 606 607 @property 608 def kind(self): 609 """Return the kind of this cursor.""" 610 return CursorKind.from_id(self._kind_id) 611 612 @property 613 def spelling(self): 614 """Return the spelling of the entity pointed at by the cursor.""" 615 if not self.kind.is_declaration(): 616 # FIXME: clang_getCursorSpelling should be fixed to not assert on 617 # this, for consistency with clang_getCursorUSR. 618 return None 619 return Cursor_spelling(self) 620 621 @property 622 def location(self): 623 """ 624 Return the source location (the starting character) of the entity 625 pointed at by the cursor. 626 """ 627 return Cursor_loc(self) 628 629 @property 630 def extent(self): 631 """ 632 Return the source range (the range of text) occupied by the entity 633 pointed at by the cursor. 634 """ 635 return Cursor_extent(self) 636 637 def get_children(self): 638 """Return an iterator for accessing the children of this cursor.""" 639 640 # FIXME: Expose iteration from CIndex, PR6125. 641 def visitor(child, parent, children): 642 # FIXME: Document this assertion in API. 643 # FIXME: There should just be an isNull method. 644 assert child != Cursor_null() 645 children.append(child) 646 return 1 # continue 647 children = [] 648 Cursor_visit(self, Cursor_visit_callback(visitor), children) 649 return iter(children) 650 651 @staticmethod 652 def from_result(res, fn, args): 653 assert isinstance(res, Cursor) 654 # FIXME: There should just be an isNull method. 655 if res == Cursor_null(): 656 return None 657 return res 658 659 ## CIndex Objects ## 660 661 # CIndex objects (derived from ClangObject) are essentially lightweight 662 # wrappers attached to some underlying object, which is exposed via CIndex as 663 # a void*. 664 665 class ClangObject(object): 666 """ 667 A helper for Clang objects. This class helps act as an intermediary for 668 the ctypes library and the Clang CIndex library. 669 """ 670 def __init__(self, obj): 671 assert isinstance(obj, c_object_p) and obj 672 self.obj = self._as_parameter_ = obj 673 674 def from_param(self): 675 return self._as_parameter_ 676 677 678 class _CXUnsavedFile(Structure): 679 """Helper for passing unsaved file arguments.""" 680 _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)] 681 682 ## Diagnostic Conversion ## 683 684 _clang_getNumDiagnostics = lib.clang_getNumDiagnostics 685 _clang_getNumDiagnostics.argtypes = [c_object_p] 686 _clang_getNumDiagnostics.restype = c_uint 687 688 _clang_getDiagnostic = lib.clang_getDiagnostic 689 _clang_getDiagnostic.argtypes = [c_object_p, c_uint] 690 _clang_getDiagnostic.restype = c_object_p 691 692 _clang_disposeDiagnostic = lib.clang_disposeDiagnostic 693 _clang_disposeDiagnostic.argtypes = [Diagnostic] 694 695 _clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity 696 _clang_getDiagnosticSeverity.argtypes = [Diagnostic] 697 _clang_getDiagnosticSeverity.restype = c_int 698 699 _clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation 700 _clang_getDiagnosticLocation.argtypes = [Diagnostic] 701 _clang_getDiagnosticLocation.restype = SourceLocation 702 703 _clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling 704 _clang_getDiagnosticSpelling.argtypes = [Diagnostic] 705 _clang_getDiagnosticSpelling.restype = _CXString 706 _clang_getDiagnosticSpelling.errcheck = _CXString.from_result 707 708 _clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges 709 _clang_getDiagnosticNumRanges.argtypes = [Diagnostic] 710 _clang_getDiagnosticNumRanges.restype = c_uint 711 712 _clang_getDiagnosticRange = lib.clang_getDiagnosticRange 713 _clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint] 714 _clang_getDiagnosticRange.restype = SourceRange 715 716 _clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts 717 _clang_getDiagnosticNumFixIts.argtypes = [Diagnostic] 718 _clang_getDiagnosticNumFixIts.restype = c_uint 719 720 _clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt 721 _clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)] 722 _clang_getDiagnosticFixIt.restype = _CXString 723 _clang_getDiagnosticFixIt.errcheck = _CXString.from_result 724 725 ### 726 727 class CompletionChunk: 728 class Kind: 729 def __init__(self, name): 730 self.name = name 731 732 def __str__(self): 733 return self.name 734 735 def __repr__(self): 736 return "<ChunkKind: %s>" % self 737 738 def __init__(self, completionString, key): 739 self.cs = completionString 740 self.key = key 741 742 def __repr__(self): 743 return "{'" + self.spelling + "', " + str(self.kind) + "}" 744 745 @property 746 def spelling(self): 747 return _clang_getCompletionChunkText(self.cs, self.key).spelling 748 749 @property 750 def kind(self): 751 res = _clang_getCompletionChunkKind(self.cs, self.key) 752 return completionChunkKindMap[res] 753 754 @property 755 def string(self): 756 res = _clang_getCompletionChunkCompletionString(self.cs, self.key) 757 758 if (res): 759 return CompletionString(res) 760 else: 761 None 762 763 def isKindOptional(self): 764 return self.kind == completionChunkKindMap[0] 765 766 def isKindTypedText(self): 767 return self.kind == completionChunkKindMap[1] 768 769 def isKindPlaceHolder(self): 770 return self.kind == completionChunkKindMap[3] 771 772 def isKindInformative(self): 773 return self.kind == completionChunkKindMap[4] 774 775 def isKindResultType(self): 776 return self.kind == completionChunkKindMap[15] 777 778 completionChunkKindMap = { 779 0: CompletionChunk.Kind("Optional"), 780 1: CompletionChunk.Kind("TypedText"), 781 2: CompletionChunk.Kind("Text"), 782 3: CompletionChunk.Kind("Placeholder"), 783 4: CompletionChunk.Kind("Informative"), 784 5: CompletionChunk.Kind("CurrentParameter"), 785 6: CompletionChunk.Kind("LeftParen"), 786 7: CompletionChunk.Kind("RightParen"), 787 8: CompletionChunk.Kind("LeftBracket"), 788 9: CompletionChunk.Kind("RightBracket"), 789 10: CompletionChunk.Kind("LeftBrace"), 790 11: CompletionChunk.Kind("RightBrace"), 791 12: CompletionChunk.Kind("LeftAngle"), 792 13: CompletionChunk.Kind("RightAngle"), 793 14: CompletionChunk.Kind("Comma"), 794 15: CompletionChunk.Kind("ResultType"), 795 16: CompletionChunk.Kind("Colon"), 796 17: CompletionChunk.Kind("SemiColon"), 797 18: CompletionChunk.Kind("Equal"), 798 19: CompletionChunk.Kind("HorizontalSpace"), 799 20: CompletionChunk.Kind("VerticalSpace")} 800 801 class CompletionString(ClangObject): 802 class Availability: 803 def __init__(self, name): 804 self.name = name 805 806 def __str__(self): 807 return self.name 808 809 def __repr__(self): 810 return "<Availability: %s>" % self 811 812 def __len__(self): 813 return _clang_getNumCompletionChunks(self.obj) 814 815 def __getitem__(self, key): 816 if len(self) <= key: 817 raise IndexError 818 return CompletionChunk(self.obj, key) 819 820 @property 821 def priority(self): 822 return _clang_getCompletionPriority(self.obj) 823 824 @property 825 def availability(self): 826 res = _clang_getCompletionAvailability(self.obj) 827 return availabilityKinds[res] 828 829 def __repr__(self): 830 return " | ".join([str(a) for a in self]) \ 831 + " || Priority: " + str(self.priority) \ 832 + " || Availability: " + str(self.availability) 833 834 availabilityKinds = { 835 0: CompletionChunk.Kind("Available"), 836 1: CompletionChunk.Kind("Deprecated"), 837 2: CompletionChunk.Kind("NotAvailable")} 838 839 class CodeCompletionResult(Structure): 840 _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)] 841 842 def __repr__(self): 843 return str(CompletionString(self.completionString)) 844 845 @property 846 def kind(self): 847 return CursorKind.from_id(self.cursorKind) 848 849 @property 850 def string(self): 851 return CompletionString(self.completionString) 852 853 class CCRStructure(Structure): 854 _fields_ = [('results', POINTER(CodeCompletionResult)), 855 ('numResults', c_int)] 856 857 def __len__(self): 858 return self.numResults 859 860 def __getitem__(self, key): 861 if len(self) <= key: 862 raise IndexError 863 864 return self.results[key] 865 866 class CodeCompletionResults(ClangObject): 867 def __init__(self, ptr): 868 assert isinstance(ptr, POINTER(CCRStructure)) and ptr 869 self.ptr = self._as_parameter_ = ptr 870 871 def from_param(self): 872 return self._as_parameter_ 873 874 def __del__(self): 875 CodeCompletionResults_dispose(self) 876 877 @property 878 def results(self): 879 return self.ptr.contents 880 881 @property 882 def diagnostics(self): 883 class DiagnosticsItr: 884 def __init__(self, ccr): 885 self.ccr= ccr 886 887 def __len__(self): 888 return int(_clang_codeCompleteGetNumDiagnostics(self.ccr)) 889 890 def __getitem__(self, key): 891 return _clang_codeCompleteGetDiagnostic(self.ccr, key) 892 893 return DiagnosticsItr(self) 894 895 896 class Index(ClangObject): 897 """ 898 The Index type provides the primary interface to the Clang CIndex library, 899 primarily by providing an interface for reading and parsing translation 900 units. 901 """ 902 903 @staticmethod 904 def create(excludeDecls=False): 905 """ 906 Create a new Index. 907 Parameters: 908 excludeDecls -- Exclude local declarations from translation units. 909 """ 910 return Index(Index_create(excludeDecls, 0)) 911 912 def __del__(self): 913 Index_dispose(self) 914 915 def read(self, path): 916 """Load the translation unit from the given AST file.""" 917 ptr = TranslationUnit_read(self, path) 918 return TranslationUnit(ptr) if ptr else None 919 920 def parse(self, path, args = [], unsaved_files = [], options = 0): 921 """ 922 Load the translation unit from the given source code file by running 923 clang and generating the AST before loading. Additional command line 924 parameters can be passed to clang via the args parameter. 925 926 In-memory contents for files can be provided by passing a list of pairs 927 to as unsaved_files, the first item should be the filenames to be mapped 928 and the second should be the contents to be substituted for the 929 file. The contents may be passed as strings or file objects. 930 """ 931 arg_array = 0 932 if len(args): 933 arg_array = (c_char_p * len(args))(* args) 934 unsaved_files_array = 0 935 if len(unsaved_files): 936 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() 937 for i,(name,value) in enumerate(unsaved_files): 938 if not isinstance(value, str): 939 # FIXME: It would be great to support an efficient version 940 # of this, one day. 941 value = value.read() 942 print value 943 if not isinstance(value, str): 944 raise TypeError,'Unexpected unsaved file contents.' 945 unsaved_files_array[i].name = name 946 unsaved_files_array[i].contents = value 947 unsaved_files_array[i].length = len(value) 948 ptr = TranslationUnit_parse(self, path, arg_array, len(args), 949 unsaved_files_array, len(unsaved_files), 950 options) 951 return TranslationUnit(ptr) if ptr else None 952 953 954 class TranslationUnit(ClangObject): 955 """ 956 The TranslationUnit class represents a source code translation unit and 957 provides read-only access to its top-level declarations. 958 """ 959 960 def __init__(self, ptr): 961 ClangObject.__init__(self, ptr) 962 963 def __del__(self): 964 TranslationUnit_dispose(self) 965 966 @property 967 def cursor(self): 968 """Retrieve the cursor that represents the given translation unit.""" 969 return TranslationUnit_cursor(self) 970 971 @property 972 def spelling(self): 973 """Get the original translation unit source file name.""" 974 return TranslationUnit_spelling(self) 975 976 def get_includes(self): 977 """ 978 Return an iterable sequence of FileInclusion objects that describe the 979 sequence of inclusions in a translation unit. The first object in 980 this sequence is always the input file. Note that this method will not 981 recursively iterate over header files included through precompiled 982 headers. 983 """ 984 def visitor(fobj, lptr, depth, includes): 985 if depth > 0: 986 loc = lptr.contents 987 includes.append(FileInclusion(loc.file, File(fobj), loc, depth)) 988 989 # Automatically adapt CIndex/ctype pointers to python objects 990 includes = [] 991 TranslationUnit_includes(self, 992 TranslationUnit_includes_callback(visitor), 993 includes) 994 return iter(includes) 995 996 @property 997 def diagnostics(self): 998 """ 999 Return an iterable (and indexable) object containing the diagnostics. 1000 """ 1001 class DiagIterator: 1002 def __init__(self, tu): 1003 self.tu = tu 1004 1005 def __len__(self): 1006 return int(_clang_getNumDiagnostics(self.tu)) 1007 1008 def __getitem__(self, key): 1009 diag = _clang_getDiagnostic(self.tu, key) 1010 if not diag: 1011 raise IndexError 1012 return Diagnostic(diag) 1013 1014 return DiagIterator(self) 1015 1016 def reparse(self, unsaved_files = [], options = 0): 1017 """ 1018 Reparse an already parsed translation unit. 1019 1020 In-memory contents for files can be provided by passing a list of pairs 1021 as unsaved_files, the first items should be the filenames to be mapped 1022 and the second should be the contents to be substituted for the 1023 file. The contents may be passed as strings or file objects. 1024 """ 1025 unsaved_files_array = 0 1026 if len(unsaved_files): 1027 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() 1028 for i,(name,value) in enumerate(unsaved_files): 1029 if not isinstance(value, str): 1030 # FIXME: It would be great to support an efficient version 1031 # of this, one day. 1032 value = value.read() 1033 print value 1034 if not isinstance(value, str): 1035 raise TypeError,'Unexpected unsaved file contents.' 1036 unsaved_files_array[i].name = name 1037 unsaved_files_array[i].contents = value 1038 unsaved_files_array[i].length = len(value) 1039 ptr = TranslationUnit_reparse(self, len(unsaved_files), 1040 unsaved_files_array, 1041 options) 1042 def codeComplete(self, path, line, column, unsaved_files = [], options = 0): 1043 """ 1044 Code complete in this translation unit. 1045 1046 In-memory contents for files can be provided by passing a list of pairs 1047 as unsaved_files, the first items should be the filenames to be mapped 1048 and the second should be the contents to be substituted for the 1049 file. The contents may be passed as strings or file objects. 1050 """ 1051 unsaved_files_array = 0 1052 if len(unsaved_files): 1053 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() 1054 for i,(name,value) in enumerate(unsaved_files): 1055 if not isinstance(value, str): 1056 # FIXME: It would be great to support an efficient version 1057 # of this, one day. 1058 value = value.read() 1059 print value 1060 if not isinstance(value, str): 1061 raise TypeError,'Unexpected unsaved file contents.' 1062 unsaved_files_array[i].name = name 1063 unsaved_files_array[i].contents = value 1064 unsaved_files_array[i].length = len(value) 1065 ptr = TranslationUnit_codeComplete(self, path, 1066 line, column, 1067 unsaved_files_array, 1068 len(unsaved_files), 1069 options) 1070 return CodeCompletionResults(ptr) if ptr else None 1071 1072 1073 class File(ClangObject): 1074 """ 1075 The File class represents a particular source file that is part of a 1076 translation unit. 1077 """ 1078 1079 @property 1080 def name(self): 1081 """Return the complete file and path name of the file.""" 1082 return _CXString_getCString(File_name(self)) 1083 1084 @property 1085 def time(self): 1086 """Return the last modification time of the file.""" 1087 return File_time(self) 1088 1089 class FileInclusion(object): 1090 """ 1091 The FileInclusion class represents the inclusion of one source file by 1092 another via a '#include' directive or as the input file for the translation 1093 unit. This class provides information about the included file, the including 1094 file, the location of the '#include' directive and the depth of the included 1095 file in the stack. Note that the input file has depth 0. 1096 """ 1097 1098 def __init__(self, src, tgt, loc, depth): 1099 self.source = src 1100 self.include = tgt 1101 self.location = loc 1102 self.depth = depth 1103 1104 @property 1105 def is_input_file(self): 1106 """True if the included file is the input file.""" 1107 return self.depth == 0 1108 1109 # Additional Functions and Types 1110 1111 # String Functions 1112 _CXString_dispose = lib.clang_disposeString 1113 _CXString_dispose.argtypes = [_CXString] 1114 1115 _CXString_getCString = lib.clang_getCString 1116 _CXString_getCString.argtypes = [_CXString] 1117 _CXString_getCString.restype = c_char_p 1118 1119 # Source Location Functions 1120 SourceLocation_loc = lib.clang_getInstantiationLocation 1121 SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p), 1122 POINTER(c_uint), POINTER(c_uint), 1123 POINTER(c_uint)] 1124 1125 # Source Range Functions 1126 SourceRange_getRange = lib.clang_getRange 1127 SourceRange_getRange.argtypes = [SourceLocation, SourceLocation] 1128 SourceRange_getRange.restype = SourceRange 1129 1130 SourceRange_start = lib.clang_getRangeStart 1131 SourceRange_start.argtypes = [SourceRange] 1132 SourceRange_start.restype = SourceLocation 1133 1134 SourceRange_end = lib.clang_getRangeEnd 1135 SourceRange_end.argtypes = [SourceRange] 1136 SourceRange_end.restype = SourceLocation 1137 1138 # CursorKind Functions 1139 CursorKind_is_decl = lib.clang_isDeclaration 1140 CursorKind_is_decl.argtypes = [CursorKind] 1141 CursorKind_is_decl.restype = bool 1142 1143 CursorKind_is_ref = lib.clang_isReference 1144 CursorKind_is_ref.argtypes = [CursorKind] 1145 CursorKind_is_ref.restype = bool 1146 1147 CursorKind_is_expr = lib.clang_isExpression 1148 CursorKind_is_expr.argtypes = [CursorKind] 1149 CursorKind_is_expr.restype = bool 1150 1151 CursorKind_is_stmt = lib.clang_isStatement 1152 CursorKind_is_stmt.argtypes = [CursorKind] 1153 CursorKind_is_stmt.restype = bool 1154 1155 CursorKind_is_attribute = lib.clang_isAttribute 1156 CursorKind_is_attribute.argtypes = [CursorKind] 1157 CursorKind_is_attribute.restype = bool 1158 1159 CursorKind_is_inv = lib.clang_isInvalid 1160 CursorKind_is_inv.argtypes = [CursorKind] 1161 CursorKind_is_inv.restype = bool 1162 1163 # Cursor Functions 1164 # TODO: Implement this function 1165 Cursor_get = lib.clang_getCursor 1166 Cursor_get.argtypes = [TranslationUnit, SourceLocation] 1167 Cursor_get.restype = Cursor 1168 1169 Cursor_null = lib.clang_getNullCursor 1170 Cursor_null.restype = Cursor 1171 1172 Cursor_usr = lib.clang_getCursorUSR 1173 Cursor_usr.argtypes = [Cursor] 1174 Cursor_usr.restype = _CXString 1175 Cursor_usr.errcheck = _CXString.from_result 1176 1177 Cursor_is_def = lib.clang_isCursorDefinition 1178 Cursor_is_def.argtypes = [Cursor] 1179 Cursor_is_def.restype = bool 1180 1181 Cursor_def = lib.clang_getCursorDefinition 1182 Cursor_def.argtypes = [Cursor] 1183 Cursor_def.restype = Cursor 1184 Cursor_def.errcheck = Cursor.from_result 1185 1186 Cursor_eq = lib.clang_equalCursors 1187 Cursor_eq.argtypes = [Cursor, Cursor] 1188 Cursor_eq.restype = c_uint 1189 1190 Cursor_spelling = lib.clang_getCursorSpelling 1191 Cursor_spelling.argtypes = [Cursor] 1192 Cursor_spelling.restype = _CXString 1193 Cursor_spelling.errcheck = _CXString.from_result 1194 1195 Cursor_displayname = lib.clang_getCursorDisplayName 1196 Cursor_displayname.argtypes = [Cursor] 1197 Cursor_displayname.restype = _CXString 1198 Cursor_displayname.errcheck = _CXString.from_result 1199 1200 Cursor_loc = lib.clang_getCursorLocation 1201 Cursor_loc.argtypes = [Cursor] 1202 Cursor_loc.restype = SourceLocation 1203 1204 Cursor_extent = lib.clang_getCursorExtent 1205 Cursor_extent.argtypes = [Cursor] 1206 Cursor_extent.restype = SourceRange 1207 1208 Cursor_ref = lib.clang_getCursorReferenced 1209 Cursor_ref.argtypes = [Cursor] 1210 Cursor_ref.restype = Cursor 1211 Cursor_ref.errcheck = Cursor.from_result 1212 1213 Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object) 1214 Cursor_visit = lib.clang_visitChildren 1215 Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object] 1216 Cursor_visit.restype = c_uint 1217 1218 # Index Functions 1219 Index_create = lib.clang_createIndex 1220 Index_create.argtypes = [c_int, c_int] 1221 Index_create.restype = c_object_p 1222 1223 Index_dispose = lib.clang_disposeIndex 1224 Index_dispose.argtypes = [Index] 1225 1226 # Translation Unit Functions 1227 TranslationUnit_read = lib.clang_createTranslationUnit 1228 TranslationUnit_read.argtypes = [Index, c_char_p] 1229 TranslationUnit_read.restype = c_object_p 1230 1231 TranslationUnit_parse = lib.clang_parseTranslationUnit 1232 TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p, 1233 c_int, c_void_p, c_int, c_int] 1234 TranslationUnit_parse.restype = c_object_p 1235 1236 TranslationUnit_reparse = lib.clang_reparseTranslationUnit 1237 TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int] 1238 TranslationUnit_reparse.restype = c_int 1239 1240 TranslationUnit_codeComplete = lib.clang_codeCompleteAt 1241 TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int, 1242 c_int, c_void_p, c_int, c_int] 1243 TranslationUnit_codeComplete.restype = POINTER(CCRStructure) 1244 1245 TranslationUnit_cursor = lib.clang_getTranslationUnitCursor 1246 TranslationUnit_cursor.argtypes = [TranslationUnit] 1247 TranslationUnit_cursor.restype = Cursor 1248 TranslationUnit_cursor.errcheck = Cursor.from_result 1249 1250 TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling 1251 TranslationUnit_spelling.argtypes = [TranslationUnit] 1252 TranslationUnit_spelling.restype = _CXString 1253 TranslationUnit_spelling.errcheck = _CXString.from_result 1254 1255 TranslationUnit_dispose = lib.clang_disposeTranslationUnit 1256 TranslationUnit_dispose.argtypes = [TranslationUnit] 1257 1258 TranslationUnit_includes_callback = CFUNCTYPE(None, 1259 c_object_p, 1260 POINTER(SourceLocation), 1261 c_uint, py_object) 1262 TranslationUnit_includes = lib.clang_getInclusions 1263 TranslationUnit_includes.argtypes = [TranslationUnit, 1264 TranslationUnit_includes_callback, 1265 py_object] 1266 1267 # File Functions 1268 File_name = lib.clang_getFileName 1269 File_name.argtypes = [File] 1270 File_name.restype = _CXString 1271 1272 File_time = lib.clang_getFileTime 1273 File_time.argtypes = [File] 1274 File_time.restype = c_uint 1275 1276 # Code completion 1277 1278 CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults 1279 CodeCompletionResults_dispose.argtypes = [CodeCompletionResults] 1280 1281 _clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics 1282 _clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults] 1283 _clang_codeCompleteGetNumDiagnostics.restype = c_int 1284 1285 _clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic 1286 _clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int] 1287 _clang_codeCompleteGetDiagnostic.restype = Diagnostic 1288 1289 _clang_getCompletionChunkText = lib.clang_getCompletionChunkText 1290 _clang_getCompletionChunkText.argtypes = [c_void_p, c_int] 1291 _clang_getCompletionChunkText.restype = _CXString 1292 1293 _clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind 1294 _clang_getCompletionChunkKind.argtypes = [c_void_p, c_int] 1295 _clang_getCompletionChunkKind.restype = c_int 1296 1297 _clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString 1298 _clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int] 1299 _clang_getCompletionChunkCompletionString.restype = c_object_p 1300 1301 _clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks 1302 _clang_getNumCompletionChunks.argtypes = [c_void_p] 1303 _clang_getNumCompletionChunks.restype = c_int 1304 1305 _clang_getCompletionAvailability = lib.clang_getCompletionAvailability 1306 _clang_getCompletionAvailability.argtypes = [c_void_p] 1307 _clang_getCompletionAvailability.restype = c_int 1308 1309 _clang_getCompletionPriority = lib.clang_getCompletionPriority 1310 _clang_getCompletionPriority.argtypes = [c_void_p] 1311 _clang_getCompletionPriority.restype = c_int 1312 1313 1314 ### 1315 1316 __all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', 1317 'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange', 1318 'SourceLocation', 'File'] 1319