| OLD | NEW |
| (Empty) |
| 1 # Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Logic for parsing a C/C++ function signature.""" | |
| 6 | |
| 7 | |
| 8 def _FindParameterListParen(name): | |
| 9 """Finds index of the "(" that denotes the start of a paremeter list.""" | |
| 10 # This loops from left-to-right, but the only reason (I think) that this | |
| 11 # is necessary (rather than reusing _FindLastCharOutsideOfBrackets), is | |
| 12 # to capture the outer-most function in the case where classes are nested. | |
| 13 start_idx = 0 | |
| 14 while True: | |
| 15 template_balance_count = 0 | |
| 16 paren_balance_count = 0 | |
| 17 while True: | |
| 18 idx = name.find('(', start_idx) | |
| 19 if idx == -1: | |
| 20 return -1 | |
| 21 template_balance_count += ( | |
| 22 name.count('<', start_idx, idx) - name.count('>', start_idx, idx)) | |
| 23 # Special: operators with angle brackets. | |
| 24 operator_idx = name.find('operator<', start_idx, idx) | |
| 25 if operator_idx != -1: | |
| 26 if name[operator_idx + 9] == '<': | |
| 27 template_balance_count -= 2 | |
| 28 else: | |
| 29 template_balance_count -= 1 | |
| 30 else: | |
| 31 operator_idx = name.find('operator>', start_idx, idx) | |
| 32 if operator_idx != -1: | |
| 33 if name[operator_idx + 9] == '>': | |
| 34 template_balance_count += 2 | |
| 35 else: | |
| 36 template_balance_count += 1 | |
| 37 | |
| 38 paren_balance_count += ( | |
| 39 name.count('(', start_idx, idx) - name.count(')', start_idx, idx)) | |
| 40 if template_balance_count == 0 and paren_balance_count == 0: | |
| 41 # Special case: skip "(anonymous namespace)". | |
| 42 if -1 != name.find('(anonymous namespace)', idx, idx + 21): | |
| 43 start_idx = idx + 21 | |
| 44 continue | |
| 45 # Special case: skip "decltype (...)" | |
| 46 if name[idx - 1] != ' ': | |
| 47 return idx | |
| 48 start_idx = idx + 1 | |
| 49 paren_balance_count += 1 | |
| 50 | |
| 51 | |
| 52 def _FindLastCharOutsideOfBrackets(name, target_char, prev_idx=None): | |
| 53 """Returns the last index of |target_char| that is not within ()s nor <>s.""" | |
| 54 paren_balance_count = 0 | |
| 55 template_balance_count = 0 | |
| 56 while True: | |
| 57 idx = name.rfind(target_char, 0, prev_idx) | |
| 58 if idx == -1: | |
| 59 return -1 | |
| 60 # It is much faster to use.find() and.count() than to loop over each | |
| 61 # character. | |
| 62 template_balance_count += ( | |
| 63 name.count('<', idx, prev_idx) - name.count('>', idx, prev_idx)) | |
| 64 paren_balance_count += ( | |
| 65 name.count('(', idx, prev_idx) - name.count(')', idx, prev_idx)) | |
| 66 if template_balance_count == 0 and paren_balance_count == 0: | |
| 67 return idx | |
| 68 prev_idx = idx | |
| 69 | |
| 70 | |
| 71 def _FindReturnValueSpace(name, paren_idx): | |
| 72 """Returns the index of the space that comes after the return type.""" | |
| 73 space_idx = paren_idx | |
| 74 # Special case: const cast operators (see tests). | |
| 75 if -1 != name.find(' const', paren_idx - 6, paren_idx): | |
| 76 space_idx = paren_idx - 6 | |
| 77 while True: | |
| 78 space_idx = _FindLastCharOutsideOfBrackets(name, ' ', space_idx) | |
| 79 # Special case: "operator new", and "operator<< <template>". | |
| 80 if -1 == space_idx or ( | |
| 81 -1 == name.find('operator', space_idx - 8, space_idx) and | |
| 82 -1 == name.find('operator<<', space_idx - 10, space_idx)): | |
| 83 break | |
| 84 space_idx -= 8 | |
| 85 return space_idx | |
| 86 | |
| 87 | |
| 88 def Parse(name): | |
| 89 """Extracts a function name from a function signature. | |
| 90 | |
| 91 See unit tests for example signatures. | |
| 92 | |
| 93 Returns: | |
| 94 A tuple of (name_without_return_type, name_without_return_type_and_params). | |
| 95 """ | |
| 96 left_paren_idx = _FindParameterListParen(name) | |
| 97 | |
| 98 if left_paren_idx > 0: | |
| 99 right_paren_idx = name.rindex(')') | |
| 100 assert right_paren_idx > left_paren_idx | |
| 101 space_idx = _FindReturnValueSpace(name, left_paren_idx) | |
| 102 return (name[space_idx + 1:], | |
| 103 name[space_idx + 1:left_paren_idx] + name[right_paren_idx + 1:]) | |
| 104 return name, name | |
| OLD | NEW |