diff --git a/Tmain/json-output-format.d/stdout-expected.txt b/Tmain/json-output-format.d/stdout-expected.txt index 021aeef721..250c277e7c 100644 --- a/Tmain/json-output-format.d/stdout-expected.txt +++ b/Tmain/json-output-format.d/stdout-expected.txt @@ -97,6 +97,7 @@ {"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C", "kindName": "struct", "path": "foreigndecl", "pattern": "declared in foreign languages"} {"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Go", "kindName": "package", "path": "imported", "pattern": "imported package"} {"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Go", "kindName": "unknown", "path": "receiverType", "pattern": "receiver type"} +{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Python", "kindName": "class", "path": "super", "pattern": "super class"} {"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Python", "kindName": "module", "path": "imported", "pattern": "imported modules"} {"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Python", "kindName": "module", "path": "indirectlyImported", "pattern": "module imported in alternative name"} {"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Python", "kindName": "module", "path": "namespace", "pattern": "namespace from where classes/variables/functions are imported"} diff --git a/Tmain/list-roles.d/stdout-expected.txt b/Tmain/list-roles.d/stdout-expected.txt index 59b5dc7277..cba7d3b7bd 100644 --- a/Tmain/list-roles.d/stdout-expected.txt +++ b/Tmain/list-roles.d/stdout-expected.txt @@ -92,6 +92,7 @@ Protobuf m/message extension on extending the messag Python Y/unknown imported on imported from the other module Python Y/unknown indirectlyImported on classes/variables/functions/modules imported in alternative name Python Y/unknown ref off (EXPERIMENTAL)referenced anyhow +Python c/class super on super class Python i/module imported on imported modules Python i/module indirectlyImported on module imported in alternative name Python i/module namespace on namespace from where classes/variables/functions are imported @@ -226,6 +227,7 @@ Protobuf m/message extension on extending the messag Python Y/unknown imported on imported from the other module Python Y/unknown indirectlyImported on classes/variables/functions/modules imported in alternative name Python Y/unknown ref off (EXPERIMENTAL)referenced anyhow +Python c/class super on super class Python i/module imported on imported modules Python i/module indirectlyImported on module imported in alternative name Python i/module namespace on namespace from where classes/variables/functions are imported diff --git a/Units/parser-python.r/reftag.d/expected.tags b/Units/parser-python.r/reftag.d/expected.tags index 7a735bfaa4..8f713c2f5d 100644 --- a/Units/parser-python.r/reftag.d/expected.tags +++ b/Units/parser-python.r/reftag.d/expected.tags @@ -1,5 +1,5 @@ a.b input.py /^import a.b$/;" i roles:imported -object input.py /^class X(object):$/;" Y roles:ref +object input.py /^class X(object):$/;" c roles:super X input.py /^class X(object):$/;" c roles:def __init__ input.py /^ def __init__(self, n):$/;" m class:X roles:def self input.py /^ def __init__(self, n):$/;" z member:X.__init__ file: roles:def diff --git a/Units/parser-python.r/simple.py.d/expected.tags b/Units/parser-python.r/simple.py.d/expected.tags index 6379eef842..a7891e5344 100644 --- a/Units/parser-python.r/simple.py.d/expected.tags +++ b/Units/parser-python.r/simple.py.d/expected.tags @@ -37,9 +37,13 @@ this input.py /^ @blah class this is seen???$/;" kind:class l _test.ignored_function.more_nesting.deeply_nested.even_more.this input.py /^ @blah class this is seen???$/;" kind:class line:41 language:Python scope:member:_test.ignored_function.more_nesting.deeply_nested.even_more file: inherits: access:private roles:def extras:qualified end:42 decorators:blah this input.py /^ @bleh def this also? good!$/;" kind:member line:42 language:Python scope:class:_test.ignored_function.more_nesting.deeply_nested.even_more.this access:public roles:def end:42 decorators:bleh _test.ignored_function.more_nesting.deeply_nested.even_more.this.this input.py /^ @bleh def this also? good!$/;" kind:member line:42 language:Python scope:class:_test.ignored_function.more_nesting.deeply_nested.even_more.this access:public roles:def extras:qualified end:42 decorators:bleh +one input.py /^class two (one):$/;" kind:class line:46 language:Python roles:super extras:reference two input.py /^class two (one):$/;" kind:class line:46 language:Python inherits:one access:public roles:def end:48 only input.py /^ def only(arg):$/;" kind:member line:48 language:Python scope:class:two access:public signature:(arg) roles:def end:48 two.only input.py /^ def only(arg):$/;" kind:member line:48 language:Python scope:class:two access:public signature:(arg) roles:def extras:qualified end:48 +A input.py /^(A, B,$/;" kind:class line:53 language:Python roles:super extras:reference +B input.py /^(A, B,$/;" kind:class line:53 language:Python roles:super extras:reference +C input.py /^C):$/;" kind:class line:54 language:Python roles:super extras:reference three input.py /^three\\$/;" kind:class line:52 language:Python inherits:A, B, C access:public roles:def end:54 foo input.py /^foo($/;" kind:function line:57 language:Python access:public signature:( x , y, z) roles:def end:60 input.py input.py 1;" kind:file line:1 language:Python roles:def extras:inputFile end:60 diff --git a/parsers/python.c b/parsers/python.c index f87752e0ba..098af15b1a 100644 --- a/parsers/python.c +++ b/parsers/python.c @@ -101,6 +101,10 @@ typedef enum { PYTHON_UNKNOWN_INDIRECTLY_IMPORTED, } pythonUnknownRole; +typedef enum { + PYTHON_CLASS_SUPERCLASS, +} pythonClassRole; + /* Roles related to `import' * ========================== * import X X = (kind:module, role:imported) @@ -135,8 +139,13 @@ static roleDefinition PythonUnknownRoles [] = { "classes/variables/functions/modules imported in alternative name" }, }; +static roleDefinition PythonClassRoles [] = { + { true, "super", "super class" }, +}; + static kindDefinition PythonKinds[COUNT_KIND] = { - {true, 'c', "class", "classes"}, + {true, 'c', "class", "classes", + .referenceOnly = false, ATTACH_ROLES(PythonClassRoles) }, {true, 'f', "function", "functions"}, {true, 'm', "member", "class members"}, {true, 'v', "variable", "variables"}, @@ -1042,13 +1051,41 @@ static void deleteTypedParam (struct typedParam *p) static void parseInheritanceList (tokenInfo *const token, vString *const inneritanceList) { + tokenInfo *lastToken = newToken (); + do { + copyToken (lastToken, token); readTokenFull (token, true); + if (lastToken->type == TOKEN_IDENTIFIER + && (token->type == ',' || token->type == ')')) + { + if (lastToken->reftag == CORK_NIL) + { + tagEntryInfo e; + initRefTagEntry(&e, vStringValue (lastToken->string), + K_CLASS, PYTHON_CLASS_SUPERCLASS); + e.lineNumber = lastToken->lineNumber; + e.filePosition = lastToken->filePosition; + lastToken->reftag = makeTagEntry (&e); + } + else + { + tagEntryInfo *e = getEntryInCorkQueue (lastToken->reftag); + if (e) + { + clearRoles(e); + e->kindIndex = K_CLASS; + assignRole(e, PYTHON_CLASS_SUPERCLASS); + } + } + } if (token->type != ')') reprCat (inneritanceList, token); } while (token->type != TOKEN_EOF && token->type != ')'); + + deleteToken (lastToken); } static void parseArglist (tokenInfo *const token,