@@ -936,7 +936,17 @@ def _params_helper1(self, stack):
936
936
elif a .startswith ("__attribute__((__const__))" ):
937
937
stack = stack [6 :]
938
938
939
- stack = stack [stack .index ("(" ) + 1 :]
939
+ last_paren_index = len (stack ) - stack [- 1 ::- 1 ].index (")" ) - 1
940
+ open_paren_count = 1
941
+ method_paren_start_idx = last_paren_index - 1
942
+ while open_paren_count > 0 :
943
+ if stack [method_paren_start_idx ] == ")" :
944
+ open_paren_count += 1
945
+ elif stack [method_paren_start_idx ] == "(" :
946
+ open_paren_count -= 1
947
+ method_paren_start_idx -= 1
948
+
949
+ stack = stack [method_paren_start_idx + 2 :]
940
950
if not stack :
941
951
return []
942
952
if (
@@ -998,33 +1008,6 @@ def __init__(self, nameStack, curClass, methinfo, curTemplate, doxygen, location
998
1008
if doxygen :
999
1009
self ["doxygen" ] = doxygen
1000
1010
1001
- # Remove leading keywords
1002
- for i , word in enumerate (nameStack ):
1003
- if word not in Resolver .C_KEYWORDS :
1004
- nameStack = nameStack [i :]
1005
- break
1006
-
1007
- if "operator" in nameStack :
1008
- rtnType = " " .join (nameStack [: nameStack .index ("operator" )])
1009
- self ["name" ] = "" .join (
1010
- nameStack [nameStack .index ("operator" ) : nameStack .index ("(" )]
1011
- )
1012
- else :
1013
- rtnType = " " .join (nameStack [: nameStack .index ("(" ) - 1 ])
1014
- self ["name" ] = " " .join (
1015
- nameStack [nameStack .index ("(" ) - 1 : nameStack .index ("(" )]
1016
- )
1017
-
1018
- if len (rtnType ) == 0 or self ["name" ] == curClass :
1019
- rtnType = "void"
1020
-
1021
- self ["rtnType" ] = (
1022
- rtnType .replace (" :: " , "::" )
1023
- .replace (" < " , "<" )
1024
- .replace (" > " , "> " )
1025
- .replace (">>" , "> >" )
1026
- .replace (" ," , "," )
1027
- )
1028
1011
1029
1012
# deal with "noexcept" specifier/operator
1030
1013
self ["noexcept" ] = None
@@ -1064,6 +1047,8 @@ def __init__(self, nameStack, curClass, methinfo, curTemplate, doxygen, location
1064
1047
break
1065
1048
1066
1049
self .update (methinfo )
1050
+ if len (self ["rtnType" ]) == 0 or self ["name" ] == curClass :
1051
+ self ["rtnType" ] = "void"
1067
1052
set_location_info (self , location )
1068
1053
1069
1054
paramsStack = self ._params_helper1 (nameStack )
@@ -1304,6 +1289,7 @@ def __init__(self, nameStack, doxygen, location, **kwargs):
1304
1289
def _filter_name (self , name ):
1305
1290
name = name .replace (" :" , ":" ).replace (": " , ":" )
1306
1291
name = name .replace (" < " , "<" )
1292
+ name = name .replace (" ( " , "(" ).replace (" ) " , ")" )
1307
1293
name = name .replace (" > " , "> " ).replace (">>" , "> >" )
1308
1294
name = name .replace (") >" , ")>" )
1309
1295
name = name .replace (" {" , "{" ).replace (" }" , "}" )
@@ -2168,7 +2154,7 @@ def finalize(self):
2168
2154
}
2169
2155
2170
2156
def parse_method_type (self , stack ):
2171
- trace_print ("meth type info" , stack )
2157
+ debug_print ("meth type info %s " , stack )
2172
2158
info = {
2173
2159
"debug" : " " .join (stack )
2174
2160
.replace (" :: " , "::" )
@@ -2183,13 +2169,57 @@ def parse_method_type(self, stack):
2183
2169
2184
2170
info .update (self ._method_type_defaults )
2185
2171
2186
- header = stack [: stack .index ("(" )]
2172
+ last_paren_index = len (stack ) - stack [- 1 ::- 1 ].index (")" ) - 1
2173
+ open_paren_count = 1
2174
+ method_paren_start_idx = last_paren_index - 1
2175
+ while open_paren_count > 0 :
2176
+ if stack [method_paren_start_idx ] == ")" :
2177
+ open_paren_count += 1
2178
+ elif stack [method_paren_start_idx ] == "(" :
2179
+ open_paren_count -= 1
2180
+ method_paren_start_idx -= 1
2181
+
2182
+ header = stack [: method_paren_start_idx + 1 ]
2187
2183
header = " " .join (header )
2184
+ # Replace fields that would mess up our re-split below
2188
2185
header = header .replace (" :: " , "::" )
2189
2186
header = header .replace (" < " , "<" )
2190
2187
header = header .replace (" > " , "> " )
2188
+ header = header .replace ("> >" , ">>" )
2191
2189
header = header .replace ("default " , "default" )
2192
2190
header = header .strip ()
2191
+ # Remove leading keywords, splitting on spaces to avoid removing keywords embedded in other words
2192
+
2193
+ # Re-split to find method declarations like A::B::meth() that were formed by joining separate tokens
2194
+ header = header .split ()
2195
+ name = header .pop ()
2196
+ for word in Resolver .C_KEYWORDS .union (set (ignoreSymbols )):
2197
+ if word in header :
2198
+ info [word ] = True
2199
+ header .remove (word )
2200
+ header = " " .join (header )
2201
+ # Now replace fields for aesthetics
2202
+ header = header .replace (" (" , "(" )
2203
+ header = header .replace ("( " , "(" )
2204
+ header = header .replace (" )" , ")" )
2205
+ header = header .replace (") " , ")" )
2206
+ header = header .replace (" ," , "," )
2207
+ if "operator" in stack :
2208
+ info ["rtnType" ] = " " .join (stack [: stack .index ("operator" )])
2209
+ op = "" .join (
2210
+ stack [stack .index ("operator" )+ 1 : method_paren_start_idx + 1 ]
2211
+ )
2212
+ if not op :
2213
+ if " " .join (["operator" , "(" , ")" , "(" ]) in " " .join (stack ):
2214
+ op = "()"
2215
+ else :
2216
+ debug_print ("Error parsing operator" )
2217
+ return None
2218
+ name = "operator" + op
2219
+ info ["operator" ] = op
2220
+ else :
2221
+ info ["rtnType" ] = header
2222
+ info ["returns" ] = info ["rtnType" ]
2193
2223
2194
2224
if stack [- 1 ] == "{" :
2195
2225
info ["defined" ] = True
@@ -2210,32 +2240,9 @@ def parse_method_type(self, stack):
2210
2240
elif stack [- 2 ] == "delete" :
2211
2241
info ["deleted" ] = True
2212
2242
2213
- r = header .split ()
2214
- name = None
2215
- if "operator" in stack : # rare case op overload defined outside of class
2216
- op = stack [stack .index ("operator" ) + 1 : stack .index ("(" )]
2217
- op = "" .join (op )
2218
- if not op :
2219
- if " " .join (["operator" , "(" , ")" , "(" ]) in " " .join (stack ):
2220
- op = "()"
2221
- else :
2222
- trace_print ("Error parsing operator" )
2223
- return None
2224
-
2225
- info ["operator" ] = op
2226
- name = "operator" + op
2227
- a = stack [: stack .index ("operator" )]
2228
-
2229
- elif r :
2230
- name = r [- 1 ]
2231
- a = r [:- 1 ] # strip name
2232
2243
2233
- if name is None :
2234
- return None
2235
2244
# if name.startswith('~'): name = name[1:]
2236
2245
2237
- while a and a [0 ] == "}" : # strip - can have multiple } }
2238
- a = a [1 :]
2239
2246
2240
2247
if "::" in name :
2241
2248
# klass,name = name.split('::') # methods can be defined outside of class
@@ -2254,35 +2261,14 @@ def parse_method_type(self, stack):
2254
2261
info ["defined" ] = True
2255
2262
info ["default" ] = True
2256
2263
name = name [1 :]
2257
- elif not a or (name == self .curClass and len (self .curClass )):
2264
+ elif (name == self .curClass and len (self .curClass )):
2258
2265
info ["constructor" ] = True
2259
2266
if "default;" in stack :
2260
2267
info ["defined" ] = True
2261
2268
info ["default" ] = True
2262
2269
2263
2270
info ["name" ] = name
2264
2271
2265
- for tag in self .C_KEYWORDS :
2266
- if tag in a :
2267
- info [tag ] = True
2268
- a .remove (tag ) # inplace
2269
- if "template" in a :
2270
- a .remove ("template" )
2271
- b = " " .join (a )
2272
- if ">" in b :
2273
- info ["template" ] = b [: b .index (">" ) + 1 ]
2274
- info ["returns" ] = b [
2275
- b .index (">" ) + 1 :
2276
- ] # find return type, could be incorrect... TODO
2277
- if "<typename" in info ["template" ].split ():
2278
- typname = info ["template" ].split ()[- 1 ]
2279
- typname = typname [:- 1 ] # strip '>'
2280
- if typname not in self ._template_typenames :
2281
- self ._template_typenames .append (typname )
2282
- else :
2283
- info ["returns" ] = " " .join (a )
2284
- else :
2285
- info ["returns" ] = " " .join (a )
2286
2272
info ["returns" ] = info ["returns" ].replace (" <" , "<" ).strip ()
2287
2273
2288
2274
## be careful with templates, do not count pointers inside template
0 commit comments