30
30
climb_type_tree ,
31
31
find_in_scope ,
32
32
find_in_workspace ,
33
+ fortran_var ,
33
34
get_use_tree ,
34
35
get_var_stack ,
35
36
set_keyword_ordering ,
36
37
)
37
38
from fortls .parse_fortran import (
39
+ DQ_STRING_REGEX ,
40
+ LOGICAL_REGEX ,
41
+ NUMBER_REGEX ,
42
+ SQ_STRING_REGEX ,
38
43
expand_name ,
39
44
fortran_ast ,
40
45
fortran_file ,
@@ -847,7 +852,7 @@ def build_comp(
847
852
)
848
853
return item_list
849
854
850
- def get_definition (self , def_file , def_line , def_char ):
855
+ def get_definition (self , def_file , def_line , def_char , hover_req = False ):
851
856
# Get full line (and possible continuations) from file
852
857
pre_lines , curr_line , _ = def_file .get_code_line (
853
858
def_line , forward = False , strip_comment = True
@@ -901,6 +906,32 @@ def get_definition(self, def_file, def_line, def_char):
901
906
for obj in self .intrinsic_funs :
902
907
if obj .name .lower () == key :
903
908
return obj
909
+
910
+ # If we have a Fortran literal constant e.g. 100, .false., etc.
911
+ # Return a dummy object with the correct type & position in the doc
912
+ if (
913
+ hover_req
914
+ and curr_scope
915
+ and (
916
+ NUMBER_REGEX .match (def_name )
917
+ or LOGICAL_REGEX .match (def_name )
918
+ or SQ_STRING_REGEX .match (def_name )
919
+ or DQ_STRING_REGEX .match (def_name )
920
+ )
921
+ ):
922
+ # The description name chosen is non-ambiguous and cannot naturally
923
+ # occur in Fortran (with/out C preproc) code
924
+ # It is invalid syntax to define a type starting with numerics
925
+ # it cannot also be a comment that requires !, c, d
926
+ # and ^= (xor_eq) operator is invalid in Fortran C++ preproc
927
+ var_obj = fortran_var (
928
+ curr_scope .file_ast ,
929
+ def_line + 1 ,
930
+ def_name ,
931
+ "0^=__LITERAL_INTERNAL_DUMMY_VAR_" ,
932
+ curr_scope .keywords ,
933
+ )
934
+ return var_obj
904
935
else :
905
936
return var_obj
906
937
return None
@@ -1141,6 +1172,26 @@ def create_hover(string, highlight):
1141
1172
else :
1142
1173
return string
1143
1174
1175
+ def create_signature_hover ():
1176
+ sig_request = request .copy ()
1177
+ sig_result = self .serve_signature (sig_request )
1178
+ try :
1179
+ arg_id = sig_result .get ("activeParameter" )
1180
+ if arg_id is not None :
1181
+ arg_info = sig_result ["signatures" ][0 ]["parameters" ][arg_id ]
1182
+ arg_doc = arg_info ["documentation" ]
1183
+ doc_split = arg_doc .find ("\n !!" )
1184
+ if doc_split < 0 :
1185
+ arg_string = f"{ arg_doc } :: { arg_info ['label' ]} "
1186
+ else :
1187
+ arg_string = (
1188
+ f"{ arg_doc [:doc_split ]} :: "
1189
+ f"{ arg_info ['label' ]} { arg_doc [doc_split :]} "
1190
+ )
1191
+ return create_hover (arg_string , True )
1192
+ except :
1193
+ pass
1194
+
1144
1195
# Get parameters from request
1145
1196
params = request ["params" ]
1146
1197
uri = params ["textDocument" ]["uri" ]
@@ -1151,7 +1202,7 @@ def create_hover(string, highlight):
1151
1202
if file_obj is None :
1152
1203
return None
1153
1204
# Find object
1154
- var_obj = self .get_definition (file_obj , def_line , def_char )
1205
+ var_obj = self .get_definition (file_obj , def_line , def_char , hover_req = True )
1155
1206
if var_obj is None :
1156
1207
return None
1157
1208
# Construct hover information
@@ -1165,30 +1216,17 @@ def create_hover(string, highlight):
1165
1216
hover_str , highlight = member .get_hover (long = True )
1166
1217
if hover_str is not None :
1167
1218
hover_array .append (create_hover (hover_str , highlight ))
1168
- return {"contents" : hover_array }
1169
- elif self .variable_hover and (var_type == 6 ):
1170
- hover_str , highlight = var_obj .get_hover ()
1171
- hover_array .append (create_hover (hover_str , highlight ))
1219
+ elif self .variable_hover and (var_type == VAR_TYPE_ID ):
1220
+ # Unless we have a Fortran literal include the desc in the hover msg
1221
+ # See get_definition for an explanaiton about this default name
1222
+ if var_obj .desc != "0^=__LITERAL_INTERNAL_DUMMY_VAR_" :
1223
+ hover_str , highlight = var_obj .get_hover ()
1224
+ hover_array .append (create_hover (hover_str , highlight ))
1225
+ # Include the signature if one is present e.g. if in an argument list
1172
1226
if self .hover_signature :
1173
- sig_request = request .copy ()
1174
- sig_result = self .serve_signature (sig_request )
1175
- try :
1176
- arg_id = sig_result .get ("activeParameter" )
1177
- if arg_id is not None :
1178
- arg_info = sig_result ["signatures" ][0 ]["parameters" ][arg_id ]
1179
- arg_doc = arg_info ["documentation" ]
1180
- doc_split = arg_doc .find ("\n !!" )
1181
- if doc_split < 0 :
1182
- arg_string = "{0} :: {1}" .format (arg_doc , arg_info ["label" ])
1183
- else :
1184
- arg_string = "{0} :: {1}{2}" .format (
1185
- arg_doc [:doc_split ],
1186
- arg_info ["label" ],
1187
- arg_doc [doc_split :],
1188
- )
1189
- hover_array .append (create_hover (arg_string , True ))
1190
- except :
1191
- pass
1227
+ hover_str = create_signature_hover ()
1228
+ if hover_str is not None :
1229
+ hover_array .append (hover_str )
1192
1230
#
1193
1231
if len (hover_array ) > 0 :
1194
1232
return {"contents" : hover_array }
0 commit comments