23
23
#include "debug.h"
24
24
#include "xtag.h"
25
25
#include "objpool.h"
26
+ #include "hint.h"
27
+ #include "routines.h"
28
+ #include "field.h"
26
29
27
30
#define isIdentifierChar (c ) \
28
31
(isalnum (c) || (c) == '_' || (c) >= 0x80)
@@ -133,12 +136,18 @@ static roleDefinition PythonModuleRoles [] = {
133
136
};
134
137
135
138
defineRolesWithCommoneElements (Unknown );
139
+ defineRolesWithCommoneElements (Class );
140
+ defineRolesWithCommoneElements (Variable );
141
+ defineRolesWithCommoneElements (Function );
136
142
137
143
static kindDefinition PythonKinds [COUNT_KIND ] = {
138
- {true, 'c' , "class" , "classes" },
139
- {true, 'f' , "function" , "functions" },
144
+ {true, 'c' , "class" , "classes" ,
145
+ .referenceOnly = false, ATTACH_ROLES (PythonClassRoles )},
146
+ {true, 'f' , "function" , "functions" ,
147
+ .referenceOnly = false, ATTACH_ROLES (PythonFunctionRoles )},
140
148
{true, 'm' , "member" , "class members" },
141
- {true, 'v' , "variable" , "variables" },
149
+ {true, 'v' , "variable" , "variables" ,
150
+ .referenceOnly = false, ATTACH_ROLES (PythonVariableRoles )},
142
151
{true, 'I' , "namespace" , "name referring a module defined in other file" },
143
152
{true, 'i' , "module" , "modules" ,
144
153
.referenceOnly = true, ATTACH_ROLES (PythonModuleRoles )},
@@ -1057,6 +1066,86 @@ static bool parseClassOrDef (tokenInfo *const token,
1057
1066
return true;
1058
1067
}
1059
1068
1069
+ struct foreachHintData
1070
+ {
1071
+ const char * module_name ;
1072
+ size_t module_namelen ;
1073
+ int kind ;
1074
+ };
1075
+
1076
+ static bool langobjIsInTheModule (const char * name , hintEntry * hint , void * data )
1077
+ {
1078
+ struct foreachHintData * hdata = data ;
1079
+
1080
+ const char * pname = getLanguageName (Lang_python );
1081
+ Assert (pname );
1082
+ const char * lang = hintFieldForType (hint , FIELD_LANGUAGE );
1083
+
1084
+ if (lang == NULL )
1085
+ return true; /* continue the finding */
1086
+
1087
+ if (strcmp (lang , pname ))
1088
+ return true; /* continue the finding */
1089
+
1090
+ const char * f = strrstr (hint -> file , hdata -> module_name );
1091
+ if (f == NULL )
1092
+ return true; /* continue the finding */
1093
+
1094
+ if (hdata -> module_namelen == 0 )
1095
+ hdata -> module_namelen = strlen (hdata -> module_name );
1096
+ const char * suffix = f + hdata -> module_namelen ;
1097
+ if (strcmp (suffix , ".py" ) != 0 )
1098
+ return true; /* continue the finding */
1099
+
1100
+ if (!(hint -> kind && * hint -> kind ))
1101
+ return true;
1102
+
1103
+ kindDefinition * kdef = NULL ;
1104
+ if (hint -> kind [1 ] == '\0' )
1105
+ kdef = getLanguageKindForLetter (Lang_python , * hint -> kind );
1106
+ else
1107
+ kdef = getLanguageKindForName (Lang_python , hint -> kind );
1108
+
1109
+ if (kdef == NULL )
1110
+ {
1111
+ /* Not found; please continue the finding. */
1112
+ return true;
1113
+ }
1114
+
1115
+ switch (kdef -> id )
1116
+ {
1117
+ case K_CLASS :
1118
+ case K_FUNCTION :
1119
+ case K_VARIABLE :
1120
+ hdata -> kind = kdef -> id ;
1121
+ /* Found; please stop the finding. */
1122
+ return false;
1123
+ default :
1124
+ /* Not found; please continue the finding. */
1125
+ return true;
1126
+ }
1127
+ }
1128
+
1129
+ static int resolveKindWithHints (const char * name , int moduleIndex )
1130
+ {
1131
+ if (!isHintAvailable ())
1132
+ return K_UNKNOWN ;
1133
+
1134
+ tagEntryInfo * e = getEntryInCorkQueue (moduleIndex );
1135
+ if (!e )
1136
+ return K_UNKNOWN ;
1137
+
1138
+ struct foreachHintData data = {
1139
+ .kind = K_UNKNOWN ,
1140
+ .module_name = e -> name ,
1141
+ .module_namelen = 0 ,
1142
+ };
1143
+
1144
+ foreachHintEntries (name , TAG_FULLMATCH , langobjIsInTheModule , & data );
1145
+
1146
+ return data .kind ;
1147
+ }
1148
+
1060
1149
static bool parseImport (tokenInfo * const token )
1061
1150
{
1062
1151
tokenInfo * fromModule = NULL ;
@@ -1120,7 +1209,8 @@ static bool parseImport (tokenInfo *const token)
1120
1209
int index ;
1121
1210
1122
1211
/* Y */
1123
- index = makeSimplePythonRefTag (name , NULL , K_UNKNOWN ,
1212
+ int kind = resolveKindWithHints (vStringValue (name -> string ), moduleIndex );
1213
+ index = makeSimplePythonRefTag (name , NULL , kind ,
1124
1214
PYTHON_COMMON_INDIRECTLY_IMPORTED ,
1125
1215
XTAG_UNKNOWN );
1126
1216
/* fill the scope field for Y */
@@ -1129,11 +1219,11 @@ static bool parseImport (tokenInfo *const token)
1129
1219
e -> extensionFields .scopeIndex = moduleIndex ;
1130
1220
1131
1221
/* Z */
1132
- index = makeSimplePythonTag (token , K_UNKNOWN );
1222
+ index = makeSimplePythonTag (token , kind );
1133
1223
/* fill the nameref filed for Y */
1134
1224
if (PythonFields [F_NAMEREF ].enabled )
1135
1225
{
1136
- vString * nameref = vStringNewInit (PythonKinds [K_UNKNOWN ].name );
1226
+ vString * nameref = vStringNewInit (PythonKinds [kind ].name );
1137
1227
vStringPut (nameref , ':' );
1138
1228
vStringCat (nameref , name -> string );
1139
1229
attachParserFieldToCorkEntry (index , PythonFields [F_NAMEREF ].ftype ,
@@ -1178,7 +1268,8 @@ static bool parseImport (tokenInfo *const token)
1178
1268
x = (kind:module, role:namespace),
1179
1269
Y = (kind:unknown, role:imported, scope:module:x) */
1180
1270
/* Y */
1181
- int index = makeSimplePythonRefTag (name , NULL , K_UNKNOWN ,
1271
+ int kind = resolveKindWithHints (vStringValue (name -> string ), moduleIndex );
1272
+ int index = makeSimplePythonRefTag (name , NULL , kind ,
1182
1273
PYTHON_COMMON_IMPORTED ,
1183
1274
XTAG_UNKNOWN );
1184
1275
/* fill the scope field for Y */
0 commit comments