@@ -96,6 +96,7 @@ typedef enum {
9696} pythonModuleRole ;
9797
9898typedef enum {
99+ PYTHON_UNKNOWN_REFERENCED ,
99100 PYTHON_UNKNOWN_IMPORTED ,
100101 PYTHON_UNKNOWN_INDIRECTLY_IMPORTED ,
101102} pythonUnknownRole ;
@@ -128,6 +129,7 @@ static roleDefinition PythonModuleRoles [] = {
128129};
129130
130131static roleDefinition PythonUnknownRoles [] = {
132+ { false,"ref" , "(EXPERIMENTAL)referenced anyhow" },
131133 { true, "imported" , "imported from the other module" },
132134 { true, "indirectlyImported" ,
133135 "classes/variables/functions/modules imported in alternative name" },
@@ -141,7 +143,7 @@ static kindDefinition PythonKinds[COUNT_KIND] = {
141143 {true, 'I' , "namespace" , "name referring a module defined in other file" },
142144 {true, 'i' , "module" , "modules" ,
143145 .referenceOnly = true, ATTACH_ROLES (PythonModuleRoles )},
144- {true, 'Y' , "unknown" , "name referring a class/variable/function/module defined in other module " ,
146+ {true, 'Y' , "unknown" , "unknwon name " ,
145147 .referenceOnly = false, ATTACH_ROLES (PythonUnknownRoles )},
146148 {false, 'z' , "parameter" , "function parameters" },
147149 {false, 'l' , "local" , "local variables" },
@@ -201,6 +203,7 @@ typedef struct {
201203 int indent ;
202204 unsigned long lineNumber ;
203205 MIOPos filePosition ;
206+ int reftag ;
204207} tokenInfo ;
205208
206209struct pythonNestingLevelUserData {
@@ -244,13 +247,23 @@ static accessType accessFromIdentifier (const vString *const ident,
244247 return ACCESS_PROTECTED ;
245248}
246249
247- static void initPythonEntry (tagEntryInfo * const e , const tokenInfo * const token ,
250+ static void useTokenAsPartOfAnotherTag (tokenInfo * const token )
251+ {
252+ if (token -> reftag == CORK_NIL )
253+ return ;
254+
255+ markCorkEntryAsPlaceholder (token -> reftag , true);
256+ token -> reftag = CORK_NIL ;
257+ }
258+
259+ static void initPythonEntry (tagEntryInfo * const e , tokenInfo * const token ,
248260 const pythonKind kind )
249261{
250262 accessType access ;
251263 int parentKind = -1 ;
252264 NestingLevel * nl ;
253265
266+ useTokenAsPartOfAnotherTag (token );
254267 initTagEntry (e , vStringValue (token -> string ), kind );
255268
256269 e -> lineNumber = token -> lineNumber ;
@@ -284,7 +297,7 @@ static void initPythonEntry (tagEntryInfo *const e, const tokenInfo *const token
284297 e -> isFileScope = true;
285298}
286299
287- static int makeClassTag (const tokenInfo * const token ,
300+ static int makeClassTag (tokenInfo * const token ,
288301 const vString * const inheritance ,
289302 const vString * const decorators )
290303{
@@ -307,7 +320,7 @@ static int makeClassTag (const tokenInfo *const token,
307320 return CORK_NIL ;
308321}
309322
310- static int makeFunctionTag (const tokenInfo * const token ,
323+ static int makeFunctionTag (tokenInfo * const token ,
311324 const vString * const arglist ,
312325 const vString * const decorators )
313326{
@@ -331,7 +344,7 @@ static int makeFunctionTag (const tokenInfo *const token,
331344 return CORK_NIL ;
332345}
333346
334- static int makeSimplePythonTag (const tokenInfo * const token , pythonKind const kind )
347+ static int makeSimplePythonTag (tokenInfo * const token , pythonKind const kind )
335348{
336349 if (PythonKinds [kind ].enabled )
337350 {
@@ -344,7 +357,7 @@ static int makeSimplePythonTag (const tokenInfo *const token, pythonKind const k
344357 return CORK_NIL ;
345358}
346359
347- static int makeSimplePythonRefTag (const tokenInfo * const token ,
360+ static int makeSimplePythonRefTag (tokenInfo * const token ,
348361 const vString * const altName ,
349362 pythonKind const kind ,
350363 int roleIndex , xtagType xtag )
@@ -354,6 +367,7 @@ static int makeSimplePythonRefTag (const tokenInfo *const token,
354367 {
355368 tagEntryInfo e ;
356369
370+ useTokenAsPartOfAnotherTag (token );
357371 initRefTagEntry (& e , vStringValue (altName ? altName : token -> string ),
358372 kind , roleIndex );
359373
@@ -393,6 +407,7 @@ static void clearPoolToken (void *data)
393407 token -> lineNumber = getInputLineNumber ();
394408 token -> filePosition = getInputFilePosition ();
395409 vStringClear (token -> string );
410+ token -> reftag = CORK_NIL ;
396411}
397412
398413static void copyToken (tokenInfo * const dest , const tokenInfo * const src )
@@ -403,6 +418,7 @@ static void copyToken (tokenInfo *const dest, const tokenInfo *const src)
403418 dest -> keyword = src -> keyword ;
404419 dest -> indent = src -> indent ;
405420 vStringCopy (dest -> string , src -> string );
421+ dest -> reftag = src -> reftag ;
406422}
407423
408424/* Skip a single or double quoted string. */
@@ -479,7 +495,7 @@ static void ungetToken (tokenInfo *const token)
479495 copyToken (NextToken , token );
480496}
481497
482- static void readTokenFull (tokenInfo * const token , bool inclWhitespaces )
498+ static void readTokenFullNoRefTag (tokenInfo * const token , bool inclWhitespaces )
483499{
484500 int c ;
485501 int n ;
@@ -694,6 +710,36 @@ static void readTokenFull (tokenInfo *const token, bool inclWhitespaces)
694710 }
695711}
696712
713+ static void readTokenFull (tokenInfo * const token , bool inclWhitespaces )
714+ {
715+ readTokenFullNoRefTag (token , inclWhitespaces );
716+
717+ if (token -> type == TOKEN_IDENTIFIER
718+ /* Don't make a ref tag for a number. */
719+ && (vStringLength (token -> string ) > 0 &&
720+ !isdigit ((unsigned char )vStringChar (token -> string , 0 )))
721+ && PythonKinds [K_UNKNOWN ].enabled
722+ && PythonUnknownRoles [PYTHON_UNKNOWN_REFERENCED ].enabled )
723+ {
724+ const bool in_subparser = (Lang_python != getInputLanguage ());
725+ if (in_subparser )
726+ pushLanguage (Lang_python );
727+
728+ tagEntryInfo e ;
729+ initRefTagEntry (& e , vStringValue (token -> string ),
730+ K_UNKNOWN , PYTHON_UNKNOWN_REFERENCED );
731+ e .lineNumber = token -> lineNumber ;
732+ e .filePosition = token -> filePosition ;
733+ NestingLevel * nl = nestingLevelsGetCurrent (PythonNestingLevels );
734+ if (nl )
735+ e .extensionFields .scopeIndex = nl -> corkIndex ;
736+ token -> reftag = makeTagEntry (& e );
737+
738+ if (in_subparser )
739+ popLanguage ();
740+ }
741+ }
742+
697743static void readToken (tokenInfo * const token )
698744{
699745 readTokenFull (token , false);
@@ -788,13 +834,18 @@ static void readQualifiedName (tokenInfo *const nameToken)
788834 vString * qualifiedName = vStringNew ();
789835 tokenInfo * token = newToken ();
790836
837+ unsigned long lineNumber = nameToken -> lineNumber ;
838+ MIOPos filePosition = nameToken -> filePosition ;
839+
840+ useTokenAsPartOfAnotherTag (nameToken );
791841 while (nameToken -> type == TOKEN_IDENTIFIER ||
792842 nameToken -> type == '.' )
793843 {
794844 vStringCat (qualifiedName , nameToken -> string );
795845 copyToken (token , nameToken );
796846
797847 readToken (nameToken );
848+ useTokenAsPartOfAnotherTag (nameToken );
798849 }
799850 /* put the last, non-matching, token back */
800851 ungetToken (nameToken );
@@ -805,6 +856,13 @@ static void readQualifiedName (tokenInfo *const nameToken)
805856
806857 deleteToken (token );
807858 vStringDelete (qualifiedName );
859+
860+ tagEntryInfo e ;
861+ initRefTagEntry (& e , vStringValue (nameToken -> string ),
862+ K_UNKNOWN , PYTHON_UNKNOWN_REFERENCED );
863+ e .lineNumber = lineNumber ;
864+ e .filePosition = filePosition ;
865+ nameToken -> reftag = makeTagEntry (& e );
808866 }
809867}
810868
@@ -1024,6 +1082,7 @@ static void parseArglist (tokenInfo *const token, const int kind,
10241082 struct typedParam * parameter ;
10251083
10261084 parameterName = newToken ();
1085+ useTokenAsPartOfAnotherTag (token );
10271086 copyToken (parameterName , token );
10281087 parameterType = parseParamTypeAnnotation (token , arglist );
10291088
@@ -1490,7 +1549,7 @@ static bool parseVariable (tokenInfo *const token, const pythonKind kind)
14901549
14911550 do
14921551 {
1493- const tokenInfo * const nameToken = nameTokens [i ];
1552+ tokenInfo * const nameToken = nameTokens [i ];
14941553 vString * * type = & (nameTypes [i ++ ]);
14951554
14961555 readToken (token );
0 commit comments