[geany/geany] 308041: Merge branch 'ctags/python'
Colomban Wendling
git-noreply at xxxxx
Wed Feb 11 17:33:19 UTC 2015
Branch: refs/heads/master
Author: Colomban Wendling <ban at herbesfolles.org>
Committer: Colomban Wendling <ban at herbesfolles.org>
Date: Wed, 11 Feb 2015 17:33:19 UTC
Commit: 308041da8d0f7ee938a075cae5d84d90da91c5eb
https://github.com/geany/geany/commit/308041da8d0f7ee938a075cae5d84d90da91c5eb
Log Message:
-----------
Merge branch 'ctags/python'
Import Python changes from https://github.com/fishman/ctags/
Modified Paths:
--------------
tagmanager/ctags/python.c
tests/ctags/Makefile.am
tests/ctags/py-skipped-string.py
tests/ctags/py-skipped-string.py.tags
Modified: tagmanager/ctags/python.c
52 lines changed, 38 insertions(+), 14 deletions(-)
===================================================================
@@ -91,32 +91,49 @@ static const char *get_class_name_from_parent (const char *parent)
* - http://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
* - http://www.python.org/dev/peps/pep-0008/#designing-for-inheritance
*/
-static pythonAccess accessFromIdentifier (const vString *const ident)
+static pythonAccess accessFromIdentifier (const vString *const ident,
+ pythonKind kind, boolean has_parent, boolean parent_is_class)
{
const char *const p = vStringValue (ident);
const size_t len = vStringLength (ident);
+ /* inside a function/method, private */
+ if (has_parent && !parent_is_class)
+ return A_PRIVATE;
/* not starting with "_", public */
- if (len < 1 || p[0] != '_')
+ else if (len < 1 || p[0] != '_')
return A_PUBLIC;
/* "__...__": magic methods */
- else if (len > 3 && p[1] == '_' && p[len - 2] == '_' && p[len - 1] == '_')
+ else if (kind == K_METHOD && parent_is_class &&
+ len > 3 && p[1] == '_' && p[len - 2] == '_' && p[len - 1] == '_')
return A_PUBLIC;
/* "__...": name mangling */
- else if (len > 1 && p[1] == '_')
+ else if (parent_is_class && len > 1 && p[1] == '_')
return A_PRIVATE;
/* "_...": suggested as non-public, but easily accessible */
else
return A_PROTECTED;
}
+static void addAccessFields (tagEntryInfo *const entry,
+ const vString *const ident, pythonKind kind,
+ boolean has_parent, boolean parent_is_class)
+{
+ pythonAccess access;
+
+ access = accessFromIdentifier (ident, kind, has_parent, parent_is_class);
+ entry->extensionFields.access = PythonAccesses [access];
+ /* FIXME: should we really set isFileScope in addition to access? */
+ if (access == A_PRIVATE)
+ entry->isFileScope = TRUE;
+}
+
/* Given a string with the contents of a line directly after the "def" keyword,
* extract all relevant information and create a tag.
*/
static void makeFunctionTag (vString *const function,
vString *const parent, int is_class_parent, const char *arglist)
{
- pythonAccess access;
tagEntryInfo tag;
initTagEntry (&tag, vStringValue (function));
@@ -147,11 +164,8 @@ static void makeFunctionTag (vString *const function,
}
}
- access = accessFromIdentifier (function);
- tag.extensionFields.access = PythonAccesses [access];
- /* FIXME: should we really set isFileScope in addition to access? */
- if (access == A_PRIVATE)
- tag.isFileScope = TRUE;
+ addAccessFields (&tag, function, is_class_parent ? K_METHOD : K_FUNCTION,
+ vStringLength (parent) > 0, is_class_parent);
makeTagEntry (&tag);
}
@@ -180,10 +194,13 @@ static void makeClassTag (vString *const class, vString *const inheritance,
}
}
tag.extensionFields.inheritance = vStringValue (inheritance);
+ addAccessFields (&tag, class, K_CLASS, vStringLength (parent) > 0,
+ is_class_parent);
makeTagEntry (&tag);
}
-static void makeVariableTag (vString *const var, vString *const parent)
+static void makeVariableTag (vString *const var, vString *const parent,
+ boolean is_class_parent)
{
tagEntryInfo tag;
initTagEntry (&tag, vStringValue (var));
@@ -194,6 +211,8 @@ static void makeVariableTag (vString *const var, vString *const parent)
tag.extensionFields.scope [0] = PythonKinds[K_CLASS].name;
tag.extensionFields.scope [1] = vStringValue (parent);
}
+ addAccessFields (&tag, var, K_VARIABLE, vStringLength (parent) > 0,
+ is_class_parent);
makeTagEntry (&tag);
}
@@ -247,6 +266,8 @@ static const char *skipEverything (const char *cp)
}
if (isIdentifierFirstCharacter ((int) *cp))
return cp;
+ if (match)
+ cp--; /* avoid jumping over the character after a skipped string */
}
return cp;
}
@@ -517,6 +538,7 @@ static char const *find_triple_start(char const *string, char const **which)
}
cp = skipString(cp);
if (!*cp) break;
+ cp--; /* avoid jumping over the character after a skipped string */
}
}
return NULL;
@@ -603,9 +625,11 @@ static const char *skipTypeDecl (const char *cp, boolean *is_class)
while (*ptr && *ptr != '=' && *ptr != '(' && !isspace(*ptr)) {
/* skip over e.g. 'cpdef numpy.ndarray[dtype=double, ndim=1]' */
if(*ptr == '[') {
- while(*ptr && *ptr != ']') ptr++;
+ while (*ptr && *ptr != ']') ptr++;
+ if (*ptr) ptr++;
+ } else {
+ ptr++;
}
- ptr++;
}
if (!*ptr || *ptr == '=') return NULL;
if (*ptr == '(') {
@@ -755,7 +779,7 @@ static void findPythonTags (void)
{
/* skip variables in methods */
if (parent_is_class || vStringLength(parent) == 0)
- makeVariableTag (name, parent);
+ makeVariableTag (name, parent, parent_is_class);
}
}
Modified: tests/ctags/Makefile.am
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -228,6 +228,7 @@ test_sources = \
prototype.h \
pure_elem.f95 \
py_constructor_arglist.py \
+ py-skipped-string.py \
qualified_types.f90 \
random.sql \
readlob.sql \
Modified: tests/ctags/py-skipped-string.py
30 lines changed, 30 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,30 @@
+# triple start string immediately after a normal string not detected
+
+def f1():
+ ''"""
+ The string above was not detected as triple start string,
+ but the one below instead.
+ """
+ print "f1"
+
+def f2():
+ ''"""
+ The string above was then detected as end string,
+ and the one below as start string again.
+ """
+ print "f2"
+
+def f3():
+ """
+ The string below is prepared so that ctags with the bug does not start a
+ new triple string. For a clean precondition for the next test.
+ ''"""
+ print "f3"
+
+# normal string immediately after a normal string not detected
+
+''" import os\
+"
+
+""' def fX():\
+'
Modified: tests/ctags/py-skipped-string.py.tags
4 lines changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,4 @@
+# format=tagmanager
+f1�16�()�0
+f2�16�()�0
+f3�16�()�0
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list