@@ -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 updateTagLine (e , token -> lineNumber , token -> filePosition );
@@ -283,7 +296,7 @@ static void initPythonEntry (tagEntryInfo *const e, const tokenInfo *const token
283296 e -> isFileScope = true;
284297}
285298
286- static int makeClassTag (const tokenInfo * const token ,
299+ static int makeClassTag (tokenInfo * const token ,
287300 const vString * const inheritance ,
288301 const vString * const decorators )
289302{
@@ -306,7 +319,7 @@ static int makeClassTag (const tokenInfo *const token,
306319 return CORK_NIL ;
307320}
308321
309- static int makeFunctionTag (const tokenInfo * const token ,
322+ static int makeFunctionTag (tokenInfo * const token ,
310323 const vString * const arglist ,
311324 const vString * const decorators )
312325{
@@ -330,7 +343,7 @@ static int makeFunctionTag (const tokenInfo *const token,
330343 return CORK_NIL ;
331344}
332345
333- static int makeSimplePythonTag (const tokenInfo * const token , pythonKind const kind )
346+ static int makeSimplePythonTag (tokenInfo * const token , pythonKind const kind )
334347{
335348 if (PythonKinds [kind ].enabled )
336349 {
@@ -343,7 +356,7 @@ static int makeSimplePythonTag (const tokenInfo *const token, pythonKind const k
343356 return CORK_NIL ;
344357}
345358
346- static int makeSimplePythonRefTag (const tokenInfo * const token ,
359+ static int makeSimplePythonRefTag (tokenInfo * const token ,
347360 const vString * const altName ,
348361 pythonKind const kind ,
349362 int roleIndex , xtagType xtag )
@@ -353,6 +366,7 @@ static int makeSimplePythonRefTag (const tokenInfo *const token,
353366 {
354367 tagEntryInfo e ;
355368
369+ useTokenAsPartOfAnotherTag (token );
356370 initRefTagEntry (& e , vStringValue (altName ? altName : token -> string ),
357371 kind , roleIndex );
358372
@@ -391,6 +405,7 @@ static void clearPoolToken (void *data)
391405 token -> lineNumber = getInputLineNumber ();
392406 token -> filePosition = getInputFilePosition ();
393407 vStringClear (token -> string );
408+ token -> reftag = CORK_NIL ;
394409}
395410
396411static void copyToken (tokenInfo * const dest , const tokenInfo * const src )
@@ -401,6 +416,7 @@ static void copyToken (tokenInfo *const dest, const tokenInfo *const src)
401416 dest -> keyword = src -> keyword ;
402417 dest -> indent = src -> indent ;
403418 vStringCopy (dest -> string , src -> string );
419+ dest -> reftag = src -> reftag ;
404420}
405421
406422/* Skip a single or double quoted string. */
@@ -477,7 +493,7 @@ static void ungetToken (tokenInfo *const token)
477493 copyToken (NextToken , token );
478494}
479495
480- static void readTokenFull (tokenInfo * const token , bool inclWhitespaces )
496+ static void readTokenFullNoRefTag (tokenInfo * const token , bool inclWhitespaces )
481497{
482498 int c ;
483499 int n ;
@@ -692,6 +708,36 @@ static void readTokenFull (tokenInfo *const token, bool inclWhitespaces)
692708 }
693709}
694710
711+ static void readTokenFull (tokenInfo * const token , bool inclWhitespaces )
712+ {
713+ readTokenFullNoRefTag (token , inclWhitespaces );
714+
715+ if (token -> type == TOKEN_IDENTIFIER
716+ /* Don't make a ref tag for a number. */
717+ && (vStringLength (token -> string ) > 0 &&
718+ !isdigit ((unsigned char )vStringChar (token -> string , 0 )))
719+ && PythonKinds [K_UNKNOWN ].enabled
720+ && PythonUnknownRoles [PYTHON_UNKNOWN_REFERENCED ].enabled )
721+ {
722+ const bool in_subparser = (Lang_python != getInputLanguage ());
723+ if (in_subparser )
724+ pushLanguage (Lang_python );
725+
726+ tagEntryInfo e ;
727+ initRefTagEntry (& e , vStringValue (token -> string ),
728+ K_UNKNOWN , PYTHON_UNKNOWN_REFERENCED );
729+ e .lineNumber = token -> lineNumber ;
730+ e .filePosition = token -> filePosition ;
731+ NestingLevel * nl = nestingLevelsGetCurrent (PythonNestingLevels );
732+ if (nl )
733+ e .extensionFields .scopeIndex = nl -> corkIndex ;
734+ token -> reftag = makeTagEntry (& e );
735+
736+ if (in_subparser )
737+ popLanguage ();
738+ }
739+ }
740+
695741static void readToken (tokenInfo * const token )
696742{
697743 readTokenFull (token , false);
@@ -786,13 +832,18 @@ static void readQualifiedName (tokenInfo *const nameToken)
786832 vString * qualifiedName = vStringNew ();
787833 tokenInfo * token = newToken ();
788834
835+ unsigned long lineNumber = nameToken -> lineNumber ;
836+ MIOPos filePosition = nameToken -> filePosition ;
837+
838+ useTokenAsPartOfAnotherTag (nameToken );
789839 while (nameToken -> type == TOKEN_IDENTIFIER ||
790840 nameToken -> type == '.' )
791841 {
792842 vStringCat (qualifiedName , nameToken -> string );
793843 copyToken (token , nameToken );
794844
795845 readToken (nameToken );
846+ useTokenAsPartOfAnotherTag (nameToken );
796847 }
797848 /* put the last, non-matching, token back */
798849 ungetToken (nameToken );
@@ -803,6 +854,13 @@ static void readQualifiedName (tokenInfo *const nameToken)
803854
804855 deleteToken (token );
805856 vStringDelete (qualifiedName );
857+
858+ tagEntryInfo e ;
859+ initRefTagEntry (& e , vStringValue (nameToken -> string ),
860+ K_UNKNOWN , PYTHON_UNKNOWN_REFERENCED );
861+ e .lineNumber = lineNumber ;
862+ e .filePosition = filePosition ;
863+ nameToken -> reftag = makeTagEntry (& e );
806864 }
807865}
808866
@@ -1022,6 +1080,7 @@ static void parseArglist (tokenInfo *const token, const int kind,
10221080 struct typedParam * parameter ;
10231081
10241082 parameterName = newToken ();
1083+ useTokenAsPartOfAnotherTag (token );
10251084 copyToken (parameterName , token );
10261085 parameterType = parseParamTypeAnnotation (token , arglist );
10271086
@@ -1488,7 +1547,7 @@ static bool parseVariable (tokenInfo *const token, const pythonKind kind)
14881547
14891548 do
14901549 {
1491- const tokenInfo * const nameToken = nameTokens [i ];
1550+ tokenInfo * const nameToken = nameTokens [i ];
14921551 vString * * type = & (nameTypes [i ++ ]);
14931552
14941553 readToken (token );
0 commit comments