Search for func, return name and some attributes Returns: dict: dict key is var name, dict value is a nested dict of attributes
(filename, ignoreTest=False)
| 173 | |
| 174 | |
| 175 | def findFunc(filename, ignoreTest=False) -> list: |
| 176 | """Search for func, return name and some attributes |
| 177 | |
| 178 | Returns: |
| 179 | dict: dict key is var name, dict value is a nested dict of attributes |
| 180 | """ |
| 181 | |
| 182 | impls = findImpl(filename, includeMod=True) |
| 183 | results = [] |
| 184 | |
| 185 | # function definition |
| 186 | with open(filename, "r") as file: |
| 187 | string = re.sub(r" +//[^\n]+\n", "\n", file.read()).replace("#[allow(unused)]", "") |
| 188 | # while '\n\n\n' in string: |
| 189 | # string = re.sub(r'\n\s+\n', r'\n\n', string) |
| 190 | string = re.sub(r"#\[cfg\(test\)\]\n+mod\s+\w+\s*\{(.|\s)+\n\}", "", string) |
| 191 | |
| 192 | pattern = r'(?P<macro>(#\[[^\]]+\]\s*)+\n)?(?P<indent> *)(?P<vis>pub\s*)?(?P<hasCrate>\(crate\)\s*)?(extern\s+"C"\s*)?(async\s*)?fn\s+(?P<name>\w+)\s*(?P<trait><[^>]+>)?\s*\((?P<args>[^\)]*)\)\s*(->\s*(?P<return>[^\{\;]+))?\s*(where[^\{]*)?\s*\{' |
| 193 | |
| 194 | matches = re.compile(pattern, re.MULTILINE | re.DOTALL) |
| 195 | for match in matches.finditer(string): |
| 196 | if ignoreTest and match.groupdict()["macro"] and "#[test]" in match.groupdict()["macro"]: |
| 197 | continue |
| 198 | results.append( |
| 199 | { |
| 200 | "name": match.groupdict()["name"], |
| 201 | # only '\n' means the func has no indent |
| 202 | "struct": lineToStruct(string[0 : match.start()].count("\n") + 2, impls)["struct"] if " " in match.groupdict()["indent"] else "", |
| 203 | "struct_trait": lineToStruct(string[0 : match.start()].count("\n") + 2, impls)["trait"] if " " in match.groupdict()["indent"] else "", |
| 204 | "line_number": string[0 : match.start()].count("\n") + 2, # not accurate |
| 205 | "modifier": "", |
| 206 | "macro": "" if match.groupdict()["macro"] == None else match.groupdict()["macro"].replace(" ", "").strip("\n").replace("\n", "; "), |
| 207 | "visibility": "internal" |
| 208 | if (match.groupdict()["macro"] and "#[private]" in match.groupdict()["macro"] or match.groupdict()["hasCrate"]) |
| 209 | else ("public" if match.groupdict()["vis"] and match.groupdict()["vis"].startswith("pub") else "private"), |
| 210 | "args": re.sub("//.+\n", "", match.groupdict()["args"]).replace(" ", "").replace("\n", "").replace(":", ": ").replace(",", ", "), |
| 211 | "return": match.groupdict()["return"].strip() if match.groupdict()["return"] else "", |
| 212 | # 'callback': '', |
| 213 | } |
| 214 | ) |
| 215 | if len(results) == 0: |
| 216 | return [] |
| 217 | |
| 218 | line_number = 0 |
| 219 | with open(filename, "r") as file: |
| 220 | func_name = "" # since function name is re-def every for loop, use this to keep the one before this line |
| 221 | last_impl_bindgen = False |
| 222 | prev_line = "" |
| 223 | |
| 224 | for line in file: |
| 225 | line_number += 1 |
| 226 | |
| 227 | if re.match(r"\s*//.+", line): # skip comments |
| 228 | continue |
| 229 | |
| 230 | """ |
| 231 | modify line number & visibility |
| 232 | """ |
no test coverage detected