mirror of
https://github.com/opnsense/src.git
synced 2026-03-07 15:51:20 -05:00
1318 lines
42 KiB
Python
1318 lines
42 KiB
Python
#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
|
|
#
|
|
# The LLVM Compiler Infrastructure
|
|
#
|
|
# This file is distributed under the University of Illinois Open Source
|
|
# License. See LICENSE.TXT for details.
|
|
#
|
|
#===------------------------------------------------------------------------===#
|
|
|
|
r"""
|
|
Clang Indexing Library Bindings
|
|
===============================
|
|
|
|
This module provides an interface to the Clang indexing library. It is a
|
|
low-level interface to the indexing library which attempts to match the Clang
|
|
API directly while also being "pythonic". Notable differences from the C API
|
|
are:
|
|
|
|
* string results are returned as Python strings, not CXString objects.
|
|
|
|
* null cursors are translated to None.
|
|
|
|
* access to child cursors is done via iteration, not visitation.
|
|
|
|
The major indexing objects are:
|
|
|
|
Index
|
|
|
|
The top-level object which manages some global library state.
|
|
|
|
TranslationUnit
|
|
|
|
High-level object encapsulating the AST for a single translation unit. These
|
|
can be loaded from .ast files or parsed on the fly.
|
|
|
|
Cursor
|
|
|
|
Generic object for representing a node in the AST.
|
|
|
|
SourceRange, SourceLocation, and File
|
|
|
|
Objects representing information about the input source.
|
|
|
|
Most object information is exposed using properties, when the underlying API
|
|
call is efficient.
|
|
"""
|
|
|
|
# TODO
|
|
# ====
|
|
#
|
|
# o API support for invalid translation units. Currently we can't even get the
|
|
# diagnostics on failure because they refer to locations in an object that
|
|
# will have been invalidated.
|
|
#
|
|
# o fix memory management issues (currently client must hold on to index and
|
|
# translation unit, or risk crashes).
|
|
#
|
|
# o expose code completion APIs.
|
|
#
|
|
# o cleanup ctypes wrapping, would be nice to separate the ctypes details more
|
|
# clearly, and hide from the external interface (i.e., help(cindex)).
|
|
#
|
|
# o implement additional SourceLocation, SourceRange, and File methods.
|
|
|
|
from ctypes import *
|
|
|
|
def get_cindex_library():
|
|
# FIXME: It's probably not the case that the library is actually found in
|
|
# this location. We need a better system of identifying and loading the
|
|
# CIndex library. It could be on path or elsewhere, or versioned, etc.
|
|
import platform
|
|
name = platform.system()
|
|
if name == 'Darwin':
|
|
return cdll.LoadLibrary('libclang.dylib')
|
|
elif name == 'Windows':
|
|
return cdll.LoadLibrary('libclang.dll')
|
|
else:
|
|
return cdll.LoadLibrary('libclang.so')
|
|
|
|
# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
|
|
# object. This is a problem, because it means that from_parameter will see an
|
|
# integer and pass the wrong value on platforms where int != void*. Work around
|
|
# this by marshalling object arguments as void**.
|
|
c_object_p = POINTER(c_void_p)
|
|
|
|
lib = get_cindex_library()
|
|
|
|
### Structures and Utility Classes ###
|
|
|
|
class _CXString(Structure):
|
|
"""Helper for transforming CXString results."""
|
|
|
|
_fields_ = [("spelling", c_char_p), ("free", c_int)]
|
|
|
|
def __del__(self):
|
|
_CXString_dispose(self)
|
|
|
|
@staticmethod
|
|
def from_result(res, fn, args):
|
|
assert isinstance(res, _CXString)
|
|
return _CXString_getCString(res)
|
|
|
|
class SourceLocation(Structure):
|
|
"""
|
|
A SourceLocation represents a particular location within a source file.
|
|
"""
|
|
_fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
|
|
_data = None
|
|
|
|
def _get_instantiation(self):
|
|
if self._data is None:
|
|
f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
|
|
SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
|
|
f = File(f) if f else None
|
|
self._data = (f, int(l.value), int(c.value), int(c.value))
|
|
return self._data
|
|
|
|
@property
|
|
def file(self):
|
|
"""Get the file represented by this source location."""
|
|
return self._get_instantiation()[0]
|
|
|
|
@property
|
|
def line(self):
|
|
"""Get the line represented by this source location."""
|
|
return self._get_instantiation()[1]
|
|
|
|
@property
|
|
def column(self):
|
|
"""Get the column represented by this source location."""
|
|
return self._get_instantiation()[2]
|
|
|
|
@property
|
|
def offset(self):
|
|
"""Get the file offset represented by this source location."""
|
|
return self._get_instantiation()[3]
|
|
|
|
def __repr__(self):
|
|
return "<SourceLocation file %r, line %r, column %r>" % (
|
|
self.file.name if self.file else None, self.line, self.column)
|
|
|
|
class SourceRange(Structure):
|
|
"""
|
|
A SourceRange describes a range of source locations within the source
|
|
code.
|
|
"""
|
|
_fields_ = [
|
|
("ptr_data", c_void_p * 2),
|
|
("begin_int_data", c_uint),
|
|
("end_int_data", c_uint)]
|
|
|
|
# FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
|
|
# object.
|
|
@staticmethod
|
|
def from_locations(start, end):
|
|
return SourceRange_getRange(start, end)
|
|
|
|
@property
|
|
def start(self):
|
|
"""
|
|
Return a SourceLocation representing the first character within a
|
|
source range.
|
|
"""
|
|
return SourceRange_start(self)
|
|
|
|
@property
|
|
def end(self):
|
|
"""
|
|
Return a SourceLocation representing the last character within a
|
|
source range.
|
|
"""
|
|
return SourceRange_end(self)
|
|
|
|
def __repr__(self):
|
|
return "<SourceRange start %r, end %r>" % (self.start, self.end)
|
|
|
|
class Diagnostic(object):
|
|
"""
|
|
A Diagnostic is a single instance of a Clang diagnostic. It includes the
|
|
diagnostic severity, the message, the location the diagnostic occurred, as
|
|
well as additional source ranges and associated fix-it hints.
|
|
"""
|
|
|
|
Ignored = 0
|
|
Note = 1
|
|
Warning = 2
|
|
Error = 3
|
|
Fatal = 4
|
|
|
|
def __init__(self, ptr):
|
|
self.ptr = ptr
|
|
|
|
def __del__(self):
|
|
_clang_disposeDiagnostic(self)
|
|
|
|
@property
|
|
def severity(self):
|
|
return _clang_getDiagnosticSeverity(self)
|
|
|
|
@property
|
|
def location(self):
|
|
return _clang_getDiagnosticLocation(self)
|
|
|
|
@property
|
|
def spelling(self):
|
|
return _clang_getDiagnosticSpelling(self)
|
|
|
|
@property
|
|
def ranges(self):
|
|
class RangeIterator:
|
|
def __init__(self, diag):
|
|
self.diag = diag
|
|
|
|
def __len__(self):
|
|
return int(_clang_getDiagnosticNumRanges(self.diag))
|
|
|
|
def __getitem__(self, key):
|
|
if (key >= len(self)):
|
|
raise IndexError
|
|
return _clang_getDiagnosticRange(self.diag, key)
|
|
|
|
return RangeIterator(self)
|
|
|
|
@property
|
|
def fixits(self):
|
|
class FixItIterator:
|
|
def __init__(self, diag):
|
|
self.diag = diag
|
|
|
|
def __len__(self):
|
|
return int(_clang_getDiagnosticNumFixIts(self.diag))
|
|
|
|
def __getitem__(self, key):
|
|
range = SourceRange()
|
|
value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
|
|
if len(value) == 0:
|
|
raise IndexError
|
|
|
|
return FixIt(range, value)
|
|
|
|
return FixItIterator(self)
|
|
|
|
def __repr__(self):
|
|
return "<Diagnostic severity %r, location %r, spelling %r>" % (
|
|
self.severity, self.location, self.spelling)
|
|
|
|
def from_param(self):
|
|
return self.ptr
|
|
|
|
class FixIt(object):
|
|
"""
|
|
A FixIt represents a transformation to be applied to the source to
|
|
"fix-it". The fix-it shouldbe applied by replacing the given source range
|
|
with the given value.
|
|
"""
|
|
|
|
def __init__(self, range, value):
|
|
self.range = range
|
|
self.value = value
|
|
|
|
def __repr__(self):
|
|
return "<FixIt range %r, value %r>" % (self.range, self.value)
|
|
|
|
### Cursor Kinds ###
|
|
|
|
class CursorKind(object):
|
|
"""
|
|
A CursorKind describes the kind of entity that a cursor points to.
|
|
"""
|
|
|
|
# The unique kind objects, indexed by id.
|
|
_kinds = []
|
|
_name_map = None
|
|
|
|
def __init__(self, value):
|
|
if value >= len(CursorKind._kinds):
|
|
CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
|
|
if CursorKind._kinds[value] is not None:
|
|
raise ValueError,'CursorKind already loaded'
|
|
self.value = value
|
|
CursorKind._kinds[value] = self
|
|
CursorKind._name_map = None
|
|
|
|
def from_param(self):
|
|
return self.value
|
|
|
|
@property
|
|
def name(self):
|
|
"""Get the enumeration name of this cursor kind."""
|
|
if self._name_map is None:
|
|
self._name_map = {}
|
|
for key,value in CursorKind.__dict__.items():
|
|
if isinstance(value,CursorKind):
|
|
self._name_map[value] = key
|
|
return self._name_map[self]
|
|
|
|
@staticmethod
|
|
def from_id(id):
|
|
if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
|
|
raise ValueError,'Unknown cursor kind'
|
|
return CursorKind._kinds[id]
|
|
|
|
@staticmethod
|
|
def get_all_kinds():
|
|
"""Return all CursorKind enumeration instances."""
|
|
return filter(None, CursorKind._kinds)
|
|
|
|
def is_declaration(self):
|
|
"""Test if this is a declaration kind."""
|
|
return CursorKind_is_decl(self)
|
|
|
|
def is_reference(self):
|
|
"""Test if this is a reference kind."""
|
|
return CursorKind_is_ref(self)
|
|
|
|
def is_expression(self):
|
|
"""Test if this is an expression kind."""
|
|
return CursorKind_is_expr(self)
|
|
|
|
def is_statement(self):
|
|
"""Test if this is a statement kind."""
|
|
return CursorKind_is_stmt(self)
|
|
|
|
def is_attribute(self):
|
|
"""Test if this is an attribute kind."""
|
|
return CursorKind_is_attribute(self)
|
|
|
|
def is_invalid(self):
|
|
"""Test if this is an invalid kind."""
|
|
return CursorKind_is_inv(self)
|
|
|
|
def __repr__(self):
|
|
return 'CursorKind.%s' % (self.name,)
|
|
|
|
# FIXME: Is there a nicer way to expose this enumeration? We could potentially
|
|
# represent the nested structure, or even build a class hierarchy. The main
|
|
# things we want for sure are (a) simple external access to kinds, (b) a place
|
|
# to hang a description and name, (c) easy to keep in sync with Index.h.
|
|
|
|
###
|
|
# Declaration Kinds
|
|
|
|
# A declaration whose specific kind is not exposed via this interface.
|
|
#
|
|
# Unexposed declarations have the same operations as any other kind of
|
|
# declaration; one can extract their location information, spelling, find their
|
|
# definitions, etc. However, the specific kind of the declaration is not
|
|
# reported.
|
|
CursorKind.UNEXPOSED_DECL = CursorKind(1)
|
|
|
|
# A C or C++ struct.
|
|
CursorKind.STRUCT_DECL = CursorKind(2)
|
|
|
|
# A C or C++ union.
|
|
CursorKind.UNION_DECL = CursorKind(3)
|
|
|
|
# A C++ class.
|
|
CursorKind.CLASS_DECL = CursorKind(4)
|
|
|
|
# An enumeration.
|
|
CursorKind.ENUM_DECL = CursorKind(5)
|
|
|
|
# A field (in C) or non-static data member (in C++) in a struct, union, or C++
|
|
# class.
|
|
CursorKind.FIELD_DECL = CursorKind(6)
|
|
|
|
# An enumerator constant.
|
|
CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
|
|
|
|
# A function.
|
|
CursorKind.FUNCTION_DECL = CursorKind(8)
|
|
|
|
# A variable.
|
|
CursorKind.VAR_DECL = CursorKind(9)
|
|
|
|
# A function or method parameter.
|
|
CursorKind.PARM_DECL = CursorKind(10)
|
|
|
|
# An Objective-C @interface.
|
|
CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
|
|
|
|
# An Objective-C @interface for a category.
|
|
CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
|
|
|
|
# An Objective-C @protocol declaration.
|
|
CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
|
|
|
|
# An Objective-C @property declaration.
|
|
CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
|
|
|
|
# An Objective-C instance variable.
|
|
CursorKind.OBJC_IVAR_DECL = CursorKind(15)
|
|
|
|
# An Objective-C instance method.
|
|
CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
|
|
|
|
# An Objective-C class method.
|
|
CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
|
|
|
|
# An Objective-C @implementation.
|
|
CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
|
|
|
|
# An Objective-C @implementation for a category.
|
|
CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
|
|
|
|
# A typedef.
|
|
CursorKind.TYPEDEF_DECL = CursorKind(20)
|
|
|
|
# A C++ class method.
|
|
CursorKind.CXX_METHOD = CursorKind(21)
|
|
|
|
# A C++ namespace.
|
|
CursorKind.NAMESPACE = CursorKind(22)
|
|
|
|
# A linkage specification, e.g. 'extern "C"'.
|
|
CursorKind.LINKAGE_SPEC = CursorKind(23)
|
|
|
|
# A C++ constructor.
|
|
CursorKind.CONSTRUCTOR = CursorKind(24)
|
|
|
|
# A C++ destructor.
|
|
CursorKind.DESTRUCTOR = CursorKind(25)
|
|
|
|
# A C++ conversion function.
|
|
CursorKind.CONVERSION_FUNCTION = CursorKind(26)
|
|
|
|
# A C++ template type parameter
|
|
CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27)
|
|
|
|
# A C++ non-type template paramater.
|
|
CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28)
|
|
|
|
# A C++ template template parameter.
|
|
CursorKind.TEMPLATE_TEMPLATE_PARAMTER = CursorKind(29)
|
|
|
|
# A C++ function template.
|
|
CursorKind.FUNCTION_TEMPLATE = CursorKind(30)
|
|
|
|
# A C++ class template.
|
|
CursorKind.CLASS_TEMPLATE = CursorKind(31)
|
|
|
|
# A C++ class template partial specialization.
|
|
CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32)
|
|
|
|
# A C++ namespace alias declaration.
|
|
CursorKind.NAMESPACE_ALIAS = CursorKind(33)
|
|
|
|
# A C++ using directive
|
|
CursorKind.USING_DIRECTIVE = CursorKind(34)
|
|
|
|
# A C++ using declaration
|
|
CursorKind.USING_DECLARATION = CursorKind(35)
|
|
|
|
###
|
|
# Reference Kinds
|
|
|
|
CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
|
|
CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
|
|
CursorKind.OBJC_CLASS_REF = CursorKind(42)
|
|
|
|
# A reference to a type declaration.
|
|
#
|
|
# A type reference occurs anywhere where a type is named but not
|
|
# declared. For example, given:
|
|
# typedef unsigned size_type;
|
|
# size_type size;
|
|
#
|
|
# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
|
|
# while the type of the variable "size" is referenced. The cursor
|
|
# referenced by the type of size is the typedef for size_type.
|
|
CursorKind.TYPE_REF = CursorKind(43)
|
|
CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
|
|
|
|
# A reference to a class template, function template, template
|
|
# template parameter, or class template partial specialization.
|
|
CursorKind.TEMPLATE_REF = CursorKind(45)
|
|
|
|
# A reference to a namespace or namepsace alias.
|
|
CursorKind.NAMESPACE_REF = CursorKind(46)
|
|
|
|
# A reference to a member of a struct, union, or class that occurs in
|
|
# some non-expression context, e.g., a designated initializer.
|
|
CursorKind.MEMBER_REF = CursorKind(47)
|
|
|
|
# A reference to a labeled statement.
|
|
CursorKind.LABEL_REF = CursorKind(48)
|
|
|
|
# A reference toa a set of overloaded functions or function templates
|
|
# that has not yet been resolved to a specific function or function template.
|
|
CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
|
|
|
|
###
|
|
# Invalid/Error Kinds
|
|
|
|
CursorKind.INVALID_FILE = CursorKind(70)
|
|
CursorKind.NO_DECL_FOUND = CursorKind(71)
|
|
CursorKind.NOT_IMPLEMENTED = CursorKind(72)
|
|
CursorKind.INVALID_CODE = CursorKind(73)
|
|
|
|
###
|
|
# Expression Kinds
|
|
|
|
# An expression whose specific kind is not exposed via this interface.
|
|
#
|
|
# Unexposed expressions have the same operations as any other kind of
|
|
# expression; one can extract their location information, spelling, children,
|
|
# etc. However, the specific kind of the expression is not reported.
|
|
CursorKind.UNEXPOSED_EXPR = CursorKind(100)
|
|
|
|
# An expression that refers to some value declaration, such as a function,
|
|
# varible, or enumerator.
|
|
CursorKind.DECL_REF_EXPR = CursorKind(101)
|
|
|
|
# An expression that refers to a member of a struct, union, class, Objective-C
|
|
# class, etc.
|
|
CursorKind.MEMBER_REF_EXPR = CursorKind(102)
|
|
|
|
# An expression that calls a function.
|
|
CursorKind.CALL_EXPR = CursorKind(103)
|
|
|
|
# An expression that sends a message to an Objective-C object or class.
|
|
CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
|
|
|
|
# An expression that represents a block literal.
|
|
CursorKind.BLOCK_EXPR = CursorKind(105)
|
|
|
|
# A statement whose specific kind is not exposed via this interface.
|
|
#
|
|
# Unexposed statements have the same operations as any other kind of statement;
|
|
# one can extract their location information, spelling, children, etc. However,
|
|
# the specific kind of the statement is not reported.
|
|
CursorKind.UNEXPOSED_STMT = CursorKind(200)
|
|
|
|
# A labelled statement in a function.
|
|
CursorKind.LABEL_STMT = CursorKind(201)
|
|
|
|
|
|
###
|
|
# Other Kinds
|
|
|
|
# Cursor that represents the translation unit itself.
|
|
#
|
|
# The translation unit cursor exists primarily to act as the root cursor for
|
|
# traversing the contents of a translation unit.
|
|
CursorKind.TRANSLATION_UNIT = CursorKind(300)
|
|
|
|
###
|
|
# Attributes
|
|
|
|
# An attribute whoe specific kind is note exposed via this interface
|
|
CursorKind.UNEXPOSED_ATTR = CursorKind(400)
|
|
|
|
CursorKind.IB_ACTION_ATTR = CursorKind(401)
|
|
CursorKind.IB_OUTLET_ATTR = CursorKind(402)
|
|
CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403)
|
|
|
|
###
|
|
# Preprocessing
|
|
CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
|
|
CursorKind.MACRO_DEFINITION = CursorKind(501)
|
|
CursorKind.MACRO_INSTANTIATION = CursorKind(502)
|
|
CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
|
|
|
|
### Cursors ###
|
|
|
|
class Cursor(Structure):
|
|
"""
|
|
The Cursor class represents a reference to an element within the AST. It
|
|
acts as a kind of iterator.
|
|
"""
|
|
_fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
|
|
|
|
def __eq__(self, other):
|
|
return Cursor_eq(self, other)
|
|
|
|
def __ne__(self, other):
|
|
return not Cursor_eq(self, other)
|
|
|
|
def is_definition(self):
|
|
"""
|
|
Returns true if the declaration pointed at by the cursor is also a
|
|
definition of that entity.
|
|
"""
|
|
return Cursor_is_def(self)
|
|
|
|
def get_definition(self):
|
|
"""
|
|
If the cursor is a reference to a declaration or a declaration of
|
|
some entity, return a cursor that points to the definition of that
|
|
entity.
|
|
"""
|
|
# TODO: Should probably check that this is either a reference or
|
|
# declaration prior to issuing the lookup.
|
|
return Cursor_def(self)
|
|
|
|
def get_usr(self):
|
|
"""Return the Unified Symbol Resultion (USR) for the entity referenced
|
|
by the given cursor (or None).
|
|
|
|
A Unified Symbol Resolution (USR) is a string that identifies a
|
|
particular entity (function, class, variable, etc.) within a
|
|
program. USRs can be compared across translation units to determine,
|
|
e.g., when references in one translation refer to an entity defined in
|
|
another translation unit."""
|
|
return Cursor_usr(self)
|
|
|
|
@property
|
|
def kind(self):
|
|
"""Return the kind of this cursor."""
|
|
return CursorKind.from_id(self._kind_id)
|
|
|
|
@property
|
|
def spelling(self):
|
|
"""Return the spelling of the entity pointed at by the cursor."""
|
|
if not self.kind.is_declaration():
|
|
# FIXME: clang_getCursorSpelling should be fixed to not assert on
|
|
# this, for consistency with clang_getCursorUSR.
|
|
return None
|
|
return Cursor_spelling(self)
|
|
|
|
@property
|
|
def location(self):
|
|
"""
|
|
Return the source location (the starting character) of the entity
|
|
pointed at by the cursor.
|
|
"""
|
|
return Cursor_loc(self)
|
|
|
|
@property
|
|
def extent(self):
|
|
"""
|
|
Return the source range (the range of text) occupied by the entity
|
|
pointed at by the cursor.
|
|
"""
|
|
return Cursor_extent(self)
|
|
|
|
def get_children(self):
|
|
"""Return an iterator for accessing the children of this cursor."""
|
|
|
|
# FIXME: Expose iteration from CIndex, PR6125.
|
|
def visitor(child, parent, children):
|
|
# FIXME: Document this assertion in API.
|
|
# FIXME: There should just be an isNull method.
|
|
assert child != Cursor_null()
|
|
children.append(child)
|
|
return 1 # continue
|
|
children = []
|
|
Cursor_visit(self, Cursor_visit_callback(visitor), children)
|
|
return iter(children)
|
|
|
|
@staticmethod
|
|
def from_result(res, fn, args):
|
|
assert isinstance(res, Cursor)
|
|
# FIXME: There should just be an isNull method.
|
|
if res == Cursor_null():
|
|
return None
|
|
return res
|
|
|
|
## CIndex Objects ##
|
|
|
|
# CIndex objects (derived from ClangObject) are essentially lightweight
|
|
# wrappers attached to some underlying object, which is exposed via CIndex as
|
|
# a void*.
|
|
|
|
class ClangObject(object):
|
|
"""
|
|
A helper for Clang objects. This class helps act as an intermediary for
|
|
the ctypes library and the Clang CIndex library.
|
|
"""
|
|
def __init__(self, obj):
|
|
assert isinstance(obj, c_object_p) and obj
|
|
self.obj = self._as_parameter_ = obj
|
|
|
|
def from_param(self):
|
|
return self._as_parameter_
|
|
|
|
|
|
class _CXUnsavedFile(Structure):
|
|
"""Helper for passing unsaved file arguments."""
|
|
_fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
|
|
|
|
## Diagnostic Conversion ##
|
|
|
|
_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
|
|
_clang_getNumDiagnostics.argtypes = [c_object_p]
|
|
_clang_getNumDiagnostics.restype = c_uint
|
|
|
|
_clang_getDiagnostic = lib.clang_getDiagnostic
|
|
_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
|
|
_clang_getDiagnostic.restype = c_object_p
|
|
|
|
_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
|
|
_clang_disposeDiagnostic.argtypes = [Diagnostic]
|
|
|
|
_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
|
|
_clang_getDiagnosticSeverity.argtypes = [Diagnostic]
|
|
_clang_getDiagnosticSeverity.restype = c_int
|
|
|
|
_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
|
|
_clang_getDiagnosticLocation.argtypes = [Diagnostic]
|
|
_clang_getDiagnosticLocation.restype = SourceLocation
|
|
|
|
_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
|
|
_clang_getDiagnosticSpelling.argtypes = [Diagnostic]
|
|
_clang_getDiagnosticSpelling.restype = _CXString
|
|
_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
|
|
|
|
_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
|
|
_clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
|
|
_clang_getDiagnosticNumRanges.restype = c_uint
|
|
|
|
_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
|
|
_clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
|
|
_clang_getDiagnosticRange.restype = SourceRange
|
|
|
|
_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
|
|
_clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
|
|
_clang_getDiagnosticNumFixIts.restype = c_uint
|
|
|
|
_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
|
|
_clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)]
|
|
_clang_getDiagnosticFixIt.restype = _CXString
|
|
_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
|
|
|
|
###
|
|
|
|
class CompletionChunk:
|
|
class Kind:
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
def __repr__(self):
|
|
return "<ChunkKind: %s>" % self
|
|
|
|
def __init__(self, completionString, key):
|
|
self.cs = completionString
|
|
self.key = key
|
|
|
|
def __repr__(self):
|
|
return "{'" + self.spelling + "', " + str(self.kind) + "}"
|
|
|
|
@property
|
|
def spelling(self):
|
|
return _clang_getCompletionChunkText(self.cs, self.key).spelling
|
|
|
|
@property
|
|
def kind(self):
|
|
res = _clang_getCompletionChunkKind(self.cs, self.key)
|
|
return completionChunkKindMap[res]
|
|
|
|
@property
|
|
def string(self):
|
|
res = _clang_getCompletionChunkCompletionString(self.cs, self.key)
|
|
|
|
if (res):
|
|
return CompletionString(res)
|
|
else:
|
|
None
|
|
|
|
def isKindOptional(self):
|
|
return self.kind == completionChunkKindMap[0]
|
|
|
|
def isKindTypedText(self):
|
|
return self.kind == completionChunkKindMap[1]
|
|
|
|
def isKindPlaceHolder(self):
|
|
return self.kind == completionChunkKindMap[3]
|
|
|
|
def isKindInformative(self):
|
|
return self.kind == completionChunkKindMap[4]
|
|
|
|
def isKindResultType(self):
|
|
return self.kind == completionChunkKindMap[15]
|
|
|
|
completionChunkKindMap = {
|
|
0: CompletionChunk.Kind("Optional"),
|
|
1: CompletionChunk.Kind("TypedText"),
|
|
2: CompletionChunk.Kind("Text"),
|
|
3: CompletionChunk.Kind("Placeholder"),
|
|
4: CompletionChunk.Kind("Informative"),
|
|
5: CompletionChunk.Kind("CurrentParameter"),
|
|
6: CompletionChunk.Kind("LeftParen"),
|
|
7: CompletionChunk.Kind("RightParen"),
|
|
8: CompletionChunk.Kind("LeftBracket"),
|
|
9: CompletionChunk.Kind("RightBracket"),
|
|
10: CompletionChunk.Kind("LeftBrace"),
|
|
11: CompletionChunk.Kind("RightBrace"),
|
|
12: CompletionChunk.Kind("LeftAngle"),
|
|
13: CompletionChunk.Kind("RightAngle"),
|
|
14: CompletionChunk.Kind("Comma"),
|
|
15: CompletionChunk.Kind("ResultType"),
|
|
16: CompletionChunk.Kind("Colon"),
|
|
17: CompletionChunk.Kind("SemiColon"),
|
|
18: CompletionChunk.Kind("Equal"),
|
|
19: CompletionChunk.Kind("HorizontalSpace"),
|
|
20: CompletionChunk.Kind("VerticalSpace")}
|
|
|
|
class CompletionString(ClangObject):
|
|
class Availability:
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
def __repr__(self):
|
|
return "<Availability: %s>" % self
|
|
|
|
def __len__(self):
|
|
return _clang_getNumCompletionChunks(self.obj)
|
|
|
|
def __getitem__(self, key):
|
|
if len(self) <= key:
|
|
raise IndexError
|
|
return CompletionChunk(self.obj, key)
|
|
|
|
@property
|
|
def priority(self):
|
|
return _clang_getCompletionPriority(self.obj)
|
|
|
|
@property
|
|
def availability(self):
|
|
res = _clang_getCompletionAvailability(self.obj)
|
|
return availabilityKinds[res]
|
|
|
|
def __repr__(self):
|
|
return " | ".join([str(a) for a in self]) \
|
|
+ " || Priority: " + str(self.priority) \
|
|
+ " || Availability: " + str(self.availability)
|
|
|
|
availabilityKinds = {
|
|
0: CompletionChunk.Kind("Available"),
|
|
1: CompletionChunk.Kind("Deprecated"),
|
|
2: CompletionChunk.Kind("NotAvailable")}
|
|
|
|
class CodeCompletionResult(Structure):
|
|
_fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
|
|
|
|
def __repr__(self):
|
|
return str(CompletionString(self.completionString))
|
|
|
|
@property
|
|
def kind(self):
|
|
return CursorKind.from_id(self.cursorKind)
|
|
|
|
@property
|
|
def string(self):
|
|
return CompletionString(self.completionString)
|
|
|
|
class CCRStructure(Structure):
|
|
_fields_ = [('results', POINTER(CodeCompletionResult)),
|
|
('numResults', c_int)]
|
|
|
|
def __len__(self):
|
|
return self.numResults
|
|
|
|
def __getitem__(self, key):
|
|
if len(self) <= key:
|
|
raise IndexError
|
|
|
|
return self.results[key]
|
|
|
|
class CodeCompletionResults(ClangObject):
|
|
def __init__(self, ptr):
|
|
assert isinstance(ptr, POINTER(CCRStructure)) and ptr
|
|
self.ptr = self._as_parameter_ = ptr
|
|
|
|
def from_param(self):
|
|
return self._as_parameter_
|
|
|
|
def __del__(self):
|
|
CodeCompletionResults_dispose(self)
|
|
|
|
@property
|
|
def results(self):
|
|
return self.ptr.contents
|
|
|
|
@property
|
|
def diagnostics(self):
|
|
class DiagnosticsItr:
|
|
def __init__(self, ccr):
|
|
self.ccr= ccr
|
|
|
|
def __len__(self):
|
|
return int(_clang_codeCompleteGetNumDiagnostics(self.ccr))
|
|
|
|
def __getitem__(self, key):
|
|
return _clang_codeCompleteGetDiagnostic(self.ccr, key)
|
|
|
|
return DiagnosticsItr(self)
|
|
|
|
|
|
class Index(ClangObject):
|
|
"""
|
|
The Index type provides the primary interface to the Clang CIndex library,
|
|
primarily by providing an interface for reading and parsing translation
|
|
units.
|
|
"""
|
|
|
|
@staticmethod
|
|
def create(excludeDecls=False):
|
|
"""
|
|
Create a new Index.
|
|
Parameters:
|
|
excludeDecls -- Exclude local declarations from translation units.
|
|
"""
|
|
return Index(Index_create(excludeDecls, 0))
|
|
|
|
def __del__(self):
|
|
Index_dispose(self)
|
|
|
|
def read(self, path):
|
|
"""Load the translation unit from the given AST file."""
|
|
ptr = TranslationUnit_read(self, path)
|
|
return TranslationUnit(ptr) if ptr else None
|
|
|
|
def parse(self, path, args = [], unsaved_files = [], options = 0):
|
|
"""
|
|
Load the translation unit from the given source code file by running
|
|
clang and generating the AST before loading. Additional command line
|
|
parameters can be passed to clang via the args parameter.
|
|
|
|
In-memory contents for files can be provided by passing a list of pairs
|
|
to as unsaved_files, the first item should be the filenames to be mapped
|
|
and the second should be the contents to be substituted for the
|
|
file. The contents may be passed as strings or file objects.
|
|
"""
|
|
arg_array = 0
|
|
if len(args):
|
|
arg_array = (c_char_p * len(args))(* args)
|
|
unsaved_files_array = 0
|
|
if len(unsaved_files):
|
|
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
|
|
for i,(name,value) in enumerate(unsaved_files):
|
|
if not isinstance(value, str):
|
|
# FIXME: It would be great to support an efficient version
|
|
# of this, one day.
|
|
value = value.read()
|
|
print value
|
|
if not isinstance(value, str):
|
|
raise TypeError,'Unexpected unsaved file contents.'
|
|
unsaved_files_array[i].name = name
|
|
unsaved_files_array[i].contents = value
|
|
unsaved_files_array[i].length = len(value)
|
|
ptr = TranslationUnit_parse(self, path, arg_array, len(args),
|
|
unsaved_files_array, len(unsaved_files),
|
|
options)
|
|
return TranslationUnit(ptr) if ptr else None
|
|
|
|
|
|
class TranslationUnit(ClangObject):
|
|
"""
|
|
The TranslationUnit class represents a source code translation unit and
|
|
provides read-only access to its top-level declarations.
|
|
"""
|
|
|
|
def __init__(self, ptr):
|
|
ClangObject.__init__(self, ptr)
|
|
|
|
def __del__(self):
|
|
TranslationUnit_dispose(self)
|
|
|
|
@property
|
|
def cursor(self):
|
|
"""Retrieve the cursor that represents the given translation unit."""
|
|
return TranslationUnit_cursor(self)
|
|
|
|
@property
|
|
def spelling(self):
|
|
"""Get the original translation unit source file name."""
|
|
return TranslationUnit_spelling(self)
|
|
|
|
def get_includes(self):
|
|
"""
|
|
Return an iterable sequence of FileInclusion objects that describe the
|
|
sequence of inclusions in a translation unit. The first object in
|
|
this sequence is always the input file. Note that this method will not
|
|
recursively iterate over header files included through precompiled
|
|
headers.
|
|
"""
|
|
def visitor(fobj, lptr, depth, includes):
|
|
if depth > 0:
|
|
loc = lptr.contents
|
|
includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
|
|
|
|
# Automatically adapt CIndex/ctype pointers to python objects
|
|
includes = []
|
|
TranslationUnit_includes(self,
|
|
TranslationUnit_includes_callback(visitor),
|
|
includes)
|
|
return iter(includes)
|
|
|
|
@property
|
|
def diagnostics(self):
|
|
"""
|
|
Return an iterable (and indexable) object containing the diagnostics.
|
|
"""
|
|
class DiagIterator:
|
|
def __init__(self, tu):
|
|
self.tu = tu
|
|
|
|
def __len__(self):
|
|
return int(_clang_getNumDiagnostics(self.tu))
|
|
|
|
def __getitem__(self, key):
|
|
diag = _clang_getDiagnostic(self.tu, key)
|
|
if not diag:
|
|
raise IndexError
|
|
return Diagnostic(diag)
|
|
|
|
return DiagIterator(self)
|
|
|
|
def reparse(self, unsaved_files = [], options = 0):
|
|
"""
|
|
Reparse an already parsed translation unit.
|
|
|
|
In-memory contents for files can be provided by passing a list of pairs
|
|
as unsaved_files, the first items should be the filenames to be mapped
|
|
and the second should be the contents to be substituted for the
|
|
file. The contents may be passed as strings or file objects.
|
|
"""
|
|
unsaved_files_array = 0
|
|
if len(unsaved_files):
|
|
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
|
|
for i,(name,value) in enumerate(unsaved_files):
|
|
if not isinstance(value, str):
|
|
# FIXME: It would be great to support an efficient version
|
|
# of this, one day.
|
|
value = value.read()
|
|
print value
|
|
if not isinstance(value, str):
|
|
raise TypeError,'Unexpected unsaved file contents.'
|
|
unsaved_files_array[i].name = name
|
|
unsaved_files_array[i].contents = value
|
|
unsaved_files_array[i].length = len(value)
|
|
ptr = TranslationUnit_reparse(self, len(unsaved_files),
|
|
unsaved_files_array,
|
|
options)
|
|
def codeComplete(self, path, line, column, unsaved_files = [], options = 0):
|
|
"""
|
|
Code complete in this translation unit.
|
|
|
|
In-memory contents for files can be provided by passing a list of pairs
|
|
as unsaved_files, the first items should be the filenames to be mapped
|
|
and the second should be the contents to be substituted for the
|
|
file. The contents may be passed as strings or file objects.
|
|
"""
|
|
unsaved_files_array = 0
|
|
if len(unsaved_files):
|
|
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
|
|
for i,(name,value) in enumerate(unsaved_files):
|
|
if not isinstance(value, str):
|
|
# FIXME: It would be great to support an efficient version
|
|
# of this, one day.
|
|
value = value.read()
|
|
print value
|
|
if not isinstance(value, str):
|
|
raise TypeError,'Unexpected unsaved file contents.'
|
|
unsaved_files_array[i].name = name
|
|
unsaved_files_array[i].contents = value
|
|
unsaved_files_array[i].length = len(value)
|
|
ptr = TranslationUnit_codeComplete(self, path,
|
|
line, column,
|
|
unsaved_files_array,
|
|
len(unsaved_files),
|
|
options)
|
|
return CodeCompletionResults(ptr) if ptr else None
|
|
|
|
|
|
class File(ClangObject):
|
|
"""
|
|
The File class represents a particular source file that is part of a
|
|
translation unit.
|
|
"""
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the complete file and path name of the file."""
|
|
return _CXString_getCString(File_name(self))
|
|
|
|
@property
|
|
def time(self):
|
|
"""Return the last modification time of the file."""
|
|
return File_time(self)
|
|
|
|
class FileInclusion(object):
|
|
"""
|
|
The FileInclusion class represents the inclusion of one source file by
|
|
another via a '#include' directive or as the input file for the translation
|
|
unit. This class provides information about the included file, the including
|
|
file, the location of the '#include' directive and the depth of the included
|
|
file in the stack. Note that the input file has depth 0.
|
|
"""
|
|
|
|
def __init__(self, src, tgt, loc, depth):
|
|
self.source = src
|
|
self.include = tgt
|
|
self.location = loc
|
|
self.depth = depth
|
|
|
|
@property
|
|
def is_input_file(self):
|
|
"""True if the included file is the input file."""
|
|
return self.depth == 0
|
|
|
|
# Additional Functions and Types
|
|
|
|
# String Functions
|
|
_CXString_dispose = lib.clang_disposeString
|
|
_CXString_dispose.argtypes = [_CXString]
|
|
|
|
_CXString_getCString = lib.clang_getCString
|
|
_CXString_getCString.argtypes = [_CXString]
|
|
_CXString_getCString.restype = c_char_p
|
|
|
|
# Source Location Functions
|
|
SourceLocation_loc = lib.clang_getInstantiationLocation
|
|
SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
|
|
POINTER(c_uint), POINTER(c_uint),
|
|
POINTER(c_uint)]
|
|
|
|
# Source Range Functions
|
|
SourceRange_getRange = lib.clang_getRange
|
|
SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
|
|
SourceRange_getRange.restype = SourceRange
|
|
|
|
SourceRange_start = lib.clang_getRangeStart
|
|
SourceRange_start.argtypes = [SourceRange]
|
|
SourceRange_start.restype = SourceLocation
|
|
|
|
SourceRange_end = lib.clang_getRangeEnd
|
|
SourceRange_end.argtypes = [SourceRange]
|
|
SourceRange_end.restype = SourceLocation
|
|
|
|
# CursorKind Functions
|
|
CursorKind_is_decl = lib.clang_isDeclaration
|
|
CursorKind_is_decl.argtypes = [CursorKind]
|
|
CursorKind_is_decl.restype = bool
|
|
|
|
CursorKind_is_ref = lib.clang_isReference
|
|
CursorKind_is_ref.argtypes = [CursorKind]
|
|
CursorKind_is_ref.restype = bool
|
|
|
|
CursorKind_is_expr = lib.clang_isExpression
|
|
CursorKind_is_expr.argtypes = [CursorKind]
|
|
CursorKind_is_expr.restype = bool
|
|
|
|
CursorKind_is_stmt = lib.clang_isStatement
|
|
CursorKind_is_stmt.argtypes = [CursorKind]
|
|
CursorKind_is_stmt.restype = bool
|
|
|
|
CursorKind_is_attribute = lib.clang_isAttribute
|
|
CursorKind_is_attribute.argtypes = [CursorKind]
|
|
CursorKind_is_attribute.restype = bool
|
|
|
|
CursorKind_is_inv = lib.clang_isInvalid
|
|
CursorKind_is_inv.argtypes = [CursorKind]
|
|
CursorKind_is_inv.restype = bool
|
|
|
|
# Cursor Functions
|
|
# TODO: Implement this function
|
|
Cursor_get = lib.clang_getCursor
|
|
Cursor_get.argtypes = [TranslationUnit, SourceLocation]
|
|
Cursor_get.restype = Cursor
|
|
|
|
Cursor_null = lib.clang_getNullCursor
|
|
Cursor_null.restype = Cursor
|
|
|
|
Cursor_usr = lib.clang_getCursorUSR
|
|
Cursor_usr.argtypes = [Cursor]
|
|
Cursor_usr.restype = _CXString
|
|
Cursor_usr.errcheck = _CXString.from_result
|
|
|
|
Cursor_is_def = lib.clang_isCursorDefinition
|
|
Cursor_is_def.argtypes = [Cursor]
|
|
Cursor_is_def.restype = bool
|
|
|
|
Cursor_def = lib.clang_getCursorDefinition
|
|
Cursor_def.argtypes = [Cursor]
|
|
Cursor_def.restype = Cursor
|
|
Cursor_def.errcheck = Cursor.from_result
|
|
|
|
Cursor_eq = lib.clang_equalCursors
|
|
Cursor_eq.argtypes = [Cursor, Cursor]
|
|
Cursor_eq.restype = c_uint
|
|
|
|
Cursor_spelling = lib.clang_getCursorSpelling
|
|
Cursor_spelling.argtypes = [Cursor]
|
|
Cursor_spelling.restype = _CXString
|
|
Cursor_spelling.errcheck = _CXString.from_result
|
|
|
|
Cursor_displayname = lib.clang_getCursorDisplayName
|
|
Cursor_displayname.argtypes = [Cursor]
|
|
Cursor_displayname.restype = _CXString
|
|
Cursor_displayname.errcheck = _CXString.from_result
|
|
|
|
Cursor_loc = lib.clang_getCursorLocation
|
|
Cursor_loc.argtypes = [Cursor]
|
|
Cursor_loc.restype = SourceLocation
|
|
|
|
Cursor_extent = lib.clang_getCursorExtent
|
|
Cursor_extent.argtypes = [Cursor]
|
|
Cursor_extent.restype = SourceRange
|
|
|
|
Cursor_ref = lib.clang_getCursorReferenced
|
|
Cursor_ref.argtypes = [Cursor]
|
|
Cursor_ref.restype = Cursor
|
|
Cursor_ref.errcheck = Cursor.from_result
|
|
|
|
Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
|
|
Cursor_visit = lib.clang_visitChildren
|
|
Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
|
|
Cursor_visit.restype = c_uint
|
|
|
|
# Index Functions
|
|
Index_create = lib.clang_createIndex
|
|
Index_create.argtypes = [c_int, c_int]
|
|
Index_create.restype = c_object_p
|
|
|
|
Index_dispose = lib.clang_disposeIndex
|
|
Index_dispose.argtypes = [Index]
|
|
|
|
# Translation Unit Functions
|
|
TranslationUnit_read = lib.clang_createTranslationUnit
|
|
TranslationUnit_read.argtypes = [Index, c_char_p]
|
|
TranslationUnit_read.restype = c_object_p
|
|
|
|
TranslationUnit_parse = lib.clang_parseTranslationUnit
|
|
TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p,
|
|
c_int, c_void_p, c_int, c_int]
|
|
TranslationUnit_parse.restype = c_object_p
|
|
|
|
TranslationUnit_reparse = lib.clang_reparseTranslationUnit
|
|
TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int]
|
|
TranslationUnit_reparse.restype = c_int
|
|
|
|
TranslationUnit_codeComplete = lib.clang_codeCompleteAt
|
|
TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int,
|
|
c_int, c_void_p, c_int, c_int]
|
|
TranslationUnit_codeComplete.restype = POINTER(CCRStructure)
|
|
|
|
TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
|
|
TranslationUnit_cursor.argtypes = [TranslationUnit]
|
|
TranslationUnit_cursor.restype = Cursor
|
|
TranslationUnit_cursor.errcheck = Cursor.from_result
|
|
|
|
TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
|
|
TranslationUnit_spelling.argtypes = [TranslationUnit]
|
|
TranslationUnit_spelling.restype = _CXString
|
|
TranslationUnit_spelling.errcheck = _CXString.from_result
|
|
|
|
TranslationUnit_dispose = lib.clang_disposeTranslationUnit
|
|
TranslationUnit_dispose.argtypes = [TranslationUnit]
|
|
|
|
TranslationUnit_includes_callback = CFUNCTYPE(None,
|
|
c_object_p,
|
|
POINTER(SourceLocation),
|
|
c_uint, py_object)
|
|
TranslationUnit_includes = lib.clang_getInclusions
|
|
TranslationUnit_includes.argtypes = [TranslationUnit,
|
|
TranslationUnit_includes_callback,
|
|
py_object]
|
|
|
|
# File Functions
|
|
File_name = lib.clang_getFileName
|
|
File_name.argtypes = [File]
|
|
File_name.restype = _CXString
|
|
|
|
File_time = lib.clang_getFileTime
|
|
File_time.argtypes = [File]
|
|
File_time.restype = c_uint
|
|
|
|
# Code completion
|
|
|
|
CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults
|
|
CodeCompletionResults_dispose.argtypes = [CodeCompletionResults]
|
|
|
|
_clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics
|
|
_clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
|
|
_clang_codeCompleteGetNumDiagnostics.restype = c_int
|
|
|
|
_clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic
|
|
_clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int]
|
|
_clang_codeCompleteGetDiagnostic.restype = Diagnostic
|
|
|
|
_clang_getCompletionChunkText = lib.clang_getCompletionChunkText
|
|
_clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
|
|
_clang_getCompletionChunkText.restype = _CXString
|
|
|
|
_clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind
|
|
_clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
|
|
_clang_getCompletionChunkKind.restype = c_int
|
|
|
|
_clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString
|
|
_clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
|
|
_clang_getCompletionChunkCompletionString.restype = c_object_p
|
|
|
|
_clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks
|
|
_clang_getNumCompletionChunks.argtypes = [c_void_p]
|
|
_clang_getNumCompletionChunks.restype = c_int
|
|
|
|
_clang_getCompletionAvailability = lib.clang_getCompletionAvailability
|
|
_clang_getCompletionAvailability.argtypes = [c_void_p]
|
|
_clang_getCompletionAvailability.restype = c_int
|
|
|
|
_clang_getCompletionPriority = lib.clang_getCompletionPriority
|
|
_clang_getCompletionPriority.argtypes = [c_void_p]
|
|
_clang_getCompletionPriority.restype = c_int
|
|
|
|
|
|
###
|
|
|
|
__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind',
|
|
'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange',
|
|
'SourceLocation', 'File']
|