summaryrefslogtreecommitdiff
path: root/bindings/python/clang/cindex.py
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /bindings/python/clang/cindex.py
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
Diffstat (limited to 'bindings/python/clang/cindex.py')
-rw-r--r--bindings/python/clang/cindex.py100
1 files changed, 67 insertions, 33 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 56fcc78763e3c..8b23ae90b982a 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -44,6 +44,7 @@ The major indexing objects are:
Most object information is exposed using properties, when the underlying API
call is efficient.
"""
+from __future__ import absolute_import, division, print_function
# TODO
# ====
@@ -63,10 +64,10 @@ call is efficient.
# o implement additional SourceLocation, SourceRange, and File methods.
from ctypes import *
-import collections
import clang.enumerations
+import os
import sys
if sys.version_info[0] == 3:
# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
@@ -108,8 +109,6 @@ if sys.version_info[0] == 3:
return x
return x.encode('utf8')
- xrange = range
-
elif sys.version_info[0] == 2:
# Python 2 strings are utf8 byte strings, no translation is needed for
# C-interop.
@@ -123,6 +122,22 @@ elif sys.version_info[0] == 2:
def b(x):
return x
+# Importing ABC-s directly from collections is deprecated since Python 3.7,
+# will stop working in Python 3.8.
+# See: https://docs.python.org/dev/whatsnew/3.7.html#id3
+if sys.version_info[:2] >= (3, 7):
+ from collections import abc as collections_abc
+else:
+ import collections as collections_abc
+
+# We only support PathLike objects on Python version with os.fspath present
+# to be consistent with the Python standard library. On older Python versions
+# we only support strings and we have dummy fspath to just pass them through.
+try:
+ fspath = os.fspath
+except AttributeError:
+ def fspath(x):
+ return x
# 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
@@ -391,7 +406,7 @@ class Diagnostic(object):
@property
def ranges(self):
- class RangeIterator:
+ class RangeIterator(object):
def __init__(self, diag):
self.diag = diag
@@ -407,7 +422,7 @@ class Diagnostic(object):
@property
def fixits(self):
- class FixItIterator:
+ class FixItIterator(object):
def __init__(self, diag):
self.diag = diag
@@ -427,7 +442,7 @@ class Diagnostic(object):
@property
def children(self):
- class ChildDiagnosticsIterator:
+ class ChildDiagnosticsIterator(object):
def __init__(self, diag):
self.diag_set = conf.lib.clang_getChildDiagnostics(diag)
@@ -547,7 +562,7 @@ class TokenGroup(object):
token_group = TokenGroup(tu, tokens_memory, tokens_count)
- for i in xrange(0, count):
+ for i in range(0, count):
token = Token()
token.int_data = tokens_array[i].int_data
token.ptr_data = tokens_array[i].ptr_data
@@ -2173,7 +2188,7 @@ class Type(Structure):
The returned object is iterable and indexable. Each item in the
container is a Type instance.
"""
- class ArgumentsIterator(collections.Sequence):
+ class ArgumentsIterator(collections_abc.Sequence):
def __init__(self, parent):
self.parent = parent
self.length = None
@@ -2254,6 +2269,12 @@ class Type(Structure):
return res
+ def get_num_template_arguments(self):
+ return conf.lib.clang_Type_getNumTemplateArguments(self)
+
+ def get_template_argument_type(self, num):
+ return conf.lib.clang_Type_getTemplateArgumentAsType(self, num)
+
def get_canonical(self):
"""
Return the canonical type for a Type.
@@ -2460,8 +2481,8 @@ SpellingCache = {
# 20: CompletionChunk.Kind("VerticalSpace")
}
-class CompletionChunk:
- class Kind:
+class CompletionChunk(object):
+ class Kind(object):
def __init__(self, name):
self.name = name
@@ -2548,7 +2569,7 @@ completionChunkKindMap = {
20: CompletionChunk.Kind("VerticalSpace")}
class CompletionString(ClangObject):
- class Availability:
+ class Availability(object):
def __init__(self, name):
self.name = name
@@ -2641,7 +2662,7 @@ class CodeCompletionResults(ClangObject):
@property
def diagnostics(self):
- class DiagnosticsItr:
+ class DiagnosticsItr(object):
def __init__(self, ccr):
self.ccr= ccr
@@ -2746,11 +2767,11 @@ class TranslationUnit(ClangObject):
etc. e.g. ["-Wall", "-I/path/to/include"].
In-memory file content can be provided via unsaved_files. This is an
- iterable of 2-tuples. The first element is the str filename. The
- second element defines the content. Content can be provided as str
- source code or as file objects (anything with a read() method). If
- a file object is being used, content will be read until EOF and the
- read cursor will not be reset to its original position.
+ iterable of 2-tuples. The first element is the filename (str or
+ PathLike). The second element defines the content. Content can be
+ provided as str source code or as file objects (anything with a read()
+ method). If a file object is being used, content will be read until EOF
+ and the read cursor will not be reset to its original position.
options is a bitwise or of TranslationUnit.PARSE_XXX flags which will
control parsing behavior.
@@ -2795,11 +2816,13 @@ class TranslationUnit(ClangObject):
if hasattr(contents, "read"):
contents = contents.read()
- unsaved_array[i].name = b(name)
+ unsaved_array[i].name = b(fspath(name))
unsaved_array[i].contents = b(contents)
unsaved_array[i].length = len(contents)
- ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array,
+ ptr = conf.lib.clang_parseTranslationUnit(index,
+ fspath(filename) if filename is not None else None,
+ args_array,
len(args), unsaved_array,
len(unsaved_files), options)
@@ -2820,11 +2843,13 @@ class TranslationUnit(ClangObject):
index is optional and is the Index instance to use. If not provided,
a default Index will be created.
+
+ filename can be str or PathLike.
"""
if index is None:
index = Index.create()
- ptr = conf.lib.clang_createTranslationUnit(index, filename)
+ ptr = conf.lib.clang_createTranslationUnit(index, fspath(filename))
if not ptr:
raise TranslationUnitLoadError(filename)
@@ -2939,7 +2964,7 @@ class TranslationUnit(ClangObject):
"""
Return an iterable (and indexable) object containing the diagnostics.
"""
- class DiagIterator:
+ class DiagIterator(object):
def __init__(self, tu):
self.tu = tu
@@ -2977,7 +3002,7 @@ class TranslationUnit(ClangObject):
print(value)
if not isinstance(value, str):
raise TypeError('Unexpected unsaved file contents.')
- unsaved_files_array[i].name = name
+ unsaved_files_array[i].name = fspath(name)
unsaved_files_array[i].contents = value
unsaved_files_array[i].length = len(value)
ptr = conf.lib.clang_reparseTranslationUnit(self, len(unsaved_files),
@@ -2996,10 +3021,10 @@ class TranslationUnit(ClangObject):
case, the reason(s) why should be available via
TranslationUnit.diagnostics().
- filename -- The path to save the translation unit to.
+ filename -- The path to save the translation unit to (str or PathLike).
"""
options = conf.lib.clang_defaultSaveOptions(self)
- result = int(conf.lib.clang_saveTranslationUnit(self, filename,
+ result = int(conf.lib.clang_saveTranslationUnit(self, fspath(filename),
options))
if result != 0:
raise TranslationUnitSaveError(result,
@@ -3041,10 +3066,10 @@ class TranslationUnit(ClangObject):
print(value)
if not isinstance(value, str):
raise TypeError('Unexpected unsaved file contents.')
- unsaved_files_array[i].name = b(name)
+ unsaved_files_array[i].name = b(fspath(name))
unsaved_files_array[i].contents = b(value)
unsaved_files_array[i].length = len(value)
- ptr = conf.lib.clang_codeCompleteAt(self, path, line, column,
+ ptr = conf.lib.clang_codeCompleteAt(self, fspath(path), line, column,
unsaved_files_array, len(unsaved_files), options)
if ptr:
return CodeCompletionResults(ptr)
@@ -3072,7 +3097,7 @@ class File(ClangObject):
@staticmethod
def from_name(translation_unit, file_name):
"""Retrieve a file handle within the given translation unit."""
- return File(conf.lib.clang_getFile(translation_unit, file_name))
+ return File(conf.lib.clang_getFile(translation_unit, fspath(file_name)))
@property
def name(self):
@@ -3171,7 +3196,7 @@ class CompileCommand(object):
Invariant : the first argument is the compiler executable
"""
length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
- for i in xrange(length):
+ for i in range(length):
yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
class CompileCommands(object):
@@ -3223,7 +3248,7 @@ class CompilationDatabase(ClangObject):
"""Builds a CompilationDatabase from the database found in buildDir"""
errorCode = c_uint()
try:
- cdb = conf.lib.clang_CompilationDatabase_fromDirectory(buildDir,
+ cdb = conf.lib.clang_CompilationDatabase_fromDirectory(fspath(buildDir),
byref(errorCode))
except CompilationDatabaseError as e:
raise CompilationDatabaseError(int(errorCode.value),
@@ -3236,7 +3261,7 @@ class CompilationDatabase(ClangObject):
build filename. Returns None if filename is not found in the database.
"""
return conf.lib.clang_CompilationDatabase_getCompileCommands(self,
- filename)
+ fspath(filename))
def getAllCompileCommands(self):
"""
@@ -3999,6 +4024,15 @@ functionList = [
Type,
Type.from_result),
+ ("clang_Type_getNumTemplateArguments",
+ [Type],
+ c_int),
+
+ ("clang_Type_getTemplateArgumentAsType",
+ [Type, c_uint],
+ Type,
+ Type.from_result),
+
("clang_Type_getOffsetOf",
[Type, c_interop_string],
c_longlong),
@@ -4062,7 +4096,7 @@ def register_functions(lib, ignore_errors):
for f in functionList:
register(f)
-class Config:
+class Config(object):
library_path = None
library_file = None
compatibility_check = True
@@ -4075,7 +4109,7 @@ class Config:
raise Exception("library path must be set before before using " \
"any other functionalities in libclang.")
- Config.library_path = path
+ Config.library_path = fspath(path)
@staticmethod
def set_library_file(filename):
@@ -4084,7 +4118,7 @@ class Config:
raise Exception("library file must be set before before using " \
"any other functionalities in libclang.")
- Config.library_file = filename
+ Config.library_file = fspath(filename)
@staticmethod
def set_compatibility_check(check_status):