summaryrefslogtreecommitdiff
path: root/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'bindings')
-rw-r--r--bindings/python/clang/cindex.py74
-rw-r--r--bindings/python/tests/cindex/test_cursor.py9
-rw-r--r--bindings/python/tests/cindex/test_translation_unit.py17
-rw-r--r--bindings/xml/comment-xml-schema.rng55
4 files changed, 142 insertions, 13 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 5e162c0e8349..70f4f36a2cfd 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -1271,6 +1271,17 @@ class Cursor(Structure):
# created.
return self._tu
+ @property
+ def referenced(self):
+ """
+ For a cursor that is a reference, returns a cursor
+ representing the entity that it references.
+ """
+ if not hasattr(self, '_referenced'):
+ self._referenced = conf.lib.clang_getCursorReferenced(self)
+
+ return self._referenced
+
def get_arguments(self):
"""Return an iterator for accessing the arguments of this cursor."""
num_args = conf.lib.clang_Cursor_getNumArguments(self)
@@ -1634,6 +1645,33 @@ class _CXUnsavedFile(Structure):
"""Helper for passing unsaved file arguments."""
_fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
+# Functions calls through the python interface are rather slow. Fortunately,
+# for most symboles, we do not need to perform a function call. Their spelling
+# never changes and is consequently provided by this spelling cache.
+SpellingCache = {
+ # 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 CompletionChunk:
class Kind:
def __init__(self, name):
@@ -1648,18 +1686,30 @@ class CompletionChunk:
def __init__(self, completionString, key):
self.cs = completionString
self.key = key
+ self.__kindNumberCache = -1
def __repr__(self):
return "{'" + self.spelling + "', " + str(self.kind) + "}"
@CachedProperty
def spelling(self):
+ if self.__kindNumber in SpellingCache:
+ return SpellingCache[self.__kindNumber]
return conf.lib.clang_getCompletionChunkText(self.cs, self.key).spelling
+ # We do not use @CachedProperty here, as the manual implementation is
+ # apparently still significantly faster. Please profile carefully if you
+ # would like to add CachedProperty back.
+ @property
+ def __kindNumber(self):
+ if self.__kindNumberCache == -1:
+ self.__kindNumberCache = \
+ conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
+ return self.__kindNumberCache
+
@CachedProperty
def kind(self):
- res = conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
- return completionChunkKindMap[res]
+ return completionChunkKindMap[self.__kindNumber]
@CachedProperty
def string(self):
@@ -1672,19 +1722,19 @@ class CompletionChunk:
None
def isKindOptional(self):
- return self.kind == completionChunkKindMap[0]
+ return self.__kindNumber == 0
def isKindTypedText(self):
- return self.kind == completionChunkKindMap[1]
+ return self.__kindNumber == 1
def isKindPlaceHolder(self):
- return self.kind == completionChunkKindMap[3]
+ return self.__kindNumber == 3
def isKindInformative(self):
- return self.kind == completionChunkKindMap[4]
+ return self.__kindNumber == 4
def isKindResultType(self):
- return self.kind == completionChunkKindMap[15]
+ return self.__kindNumber == 15
completionChunkKindMap = {
0: CompletionChunk.Kind("Optional"),
@@ -1965,7 +2015,7 @@ class TranslationUnit(ClangObject):
len(args), unsaved_array,
len(unsaved_files), options)
- if ptr is None:
+ if not ptr:
raise TranslationUnitLoadError("Error parsing translation unit.")
return cls(ptr, index=index)
@@ -1987,7 +2037,7 @@ class TranslationUnit(ClangObject):
index = Index.create()
ptr = conf.lib.clang_createTranslationUnit(index, filename)
- if ptr is None:
+ if not ptr:
raise TranslationUnitLoadError(filename)
return cls(ptr=ptr, index=index)
@@ -3046,13 +3096,13 @@ class Config:
Config.library_path = path
@staticmethod
- def set_library_file(file):
- """Set the exact location of libclang from"""
+ def set_library_file(filename):
+ """Set the exact location of libclang"""
if Config.loaded:
raise Exception("library file must be set before before using " \
"any other functionalities in libclang.")
- Config.library_file = path
+ Config.library_file = filename
@staticmethod
def set_compatibility_check(check_status):
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
index edb209b52b96..a27525cfe553 100644
--- a/bindings/python/tests/cindex/test_cursor.py
+++ b/bindings/python/tests/cindex/test_cursor.py
@@ -250,3 +250,12 @@ def test_get_arguments():
assert len(arguments) == 2
assert arguments[0].spelling == "i"
assert arguments[1].spelling == "j"
+
+def test_referenced():
+ tu = get_tu('void foo(); void bar() { foo(); }')
+ foo = get_cursor(tu, 'foo')
+ bar = get_cursor(tu, 'bar')
+ for c in bar.get_children():
+ if c.kind == CursorKind.CALL_EXPR:
+ assert c.referenced.spelling == foo.spelling
+ break
diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py
index c91f126097ac..f77998e52457 100644
--- a/bindings/python/tests/cindex/test_translation_unit.py
+++ b/bindings/python/tests/cindex/test_translation_unit.py
@@ -8,6 +8,7 @@ from clang.cindex import Index
from clang.cindex import SourceLocation
from clang.cindex import SourceRange
from clang.cindex import TranslationUnitSaveError
+from clang.cindex import TranslationUnitLoadError
from clang.cindex import TranslationUnit
from .util import get_cursor
from .util import get_tu
@@ -239,3 +240,19 @@ def test_get_tokens_gc():
del tokens
gc.collect()
gc.collect() # Just in case.
+
+def test_fail_from_source():
+ path = os.path.join(kInputsDir, 'non-existent.cpp')
+ try:
+ tu = TranslationUnit.from_source(path)
+ except TranslationUnitLoadError:
+ tu = None
+ assert tu == None
+
+def test_fail_from_ast_file():
+ path = os.path.join(kInputsDir, 'non-existent.ast')
+ try:
+ tu = TranslationUnit.from_ast_file(path)
+ except TranslationUnitLoadError:
+ tu = None
+ assert tu == None
diff --git a/bindings/xml/comment-xml-schema.rng b/bindings/xml/comment-xml-schema.rng
index d98f405cf9e7..22371dfed1e4 100644
--- a/bindings/xml/comment-xml-schema.rng
+++ b/bindings/xml/comment-xml-schema.rng
@@ -25,6 +25,9 @@
<ref name="USR" />
</optional>
<optional>
+ <ref name="Headerfile" />
+ </optional>
+ <optional>
<ref name="Declaration" />
</optional>
<optional>
@@ -74,6 +77,9 @@
</optional>
<!-- TODO: Add exception specification. -->
<optional>
+ <ref name="Headerfile" />
+ </optional>
+ <optional>
<ref name="Declaration" />
</optional>
<optional>
@@ -121,6 +127,9 @@
<ref name="USR" />
</optional>
<optional>
+ <ref name="Headerfile" />
+ </optional>
+ <optional>
<ref name="Declaration" />
</optional>
<optional>
@@ -153,6 +162,9 @@
<ref name="USR" />
</optional>
<optional>
+ <ref name="Headerfile" />
+ </optional>
+ <optional>
<ref name="Declaration" />
</optional>
<optional>
@@ -186,6 +198,9 @@
<ref name="USR" />
</optional>
<optional>
+ <ref name="Headerfile" />
+ </optional>
+ <optional>
<ref name="Declaration" />
</optional>
<optional>
@@ -219,6 +234,9 @@
<ref name="USR" />
</optional>
<optional>
+ <ref name="Headerfile" />
+ </optional>
+ <optional>
<ref name="Declaration" />
</optional>
<optional>
@@ -252,6 +270,9 @@
<ref name="USR" />
</optional>
<optional>
+ <ref name="Headerfile" />
+ </optional>
+ <optional>
<ref name="Declaration" />
</optional>
<optional>
@@ -329,6 +350,14 @@
</element>
</define>
+ <define name="Headerfile">
+ <element name="Headerfile">
+ <oneOrMore>
+ <ref name="TextBlockContent" />
+ </oneOrMore>
+ </element>
+ </define>
+
<define name="Discussion">
<element name="Discussion">
<zeroOrMore>
@@ -409,7 +438,7 @@
<define name="Availability">
<element name="Availability">
<attribute name="distribution">
- <data type="string" />
+ <data type="string" />
</attribute>
<optional>
<element name="IntroducedInVersion">
@@ -470,6 +499,30 @@
<define name="TextBlockContent">
<choice>
<element name="Para">
+ <optional>
+ <attribute name="kind">
+ <choice>
+ <value>attention</value>
+ <value>author</value>
+ <value>authors</value>
+ <value>bug</value>
+ <value>copyright</value>
+ <value>date</value>
+ <value>invariant</value>
+ <value>note</value>
+ <value>post</value>
+ <value>pre</value>
+ <value>remark</value>
+ <value>remarks</value>
+ <value>sa</value>
+ <value>see</value>
+ <value>since</value>
+ <value>todo</value>
+ <value>version</value>
+ <value>warning</value>
+ </choice>
+ </attribute>
+ </optional>
<zeroOrMore>
<ref name="TextInlineContent" />
</zeroOrMore>