| OLD | NEW |
| 1 # Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Logic for parsing a C/C++ function signature.""" | 5 """Logic for parsing a C/C++ function signature.""" |
| 6 | 6 |
| 7 | 7 |
| 8 def _FindParameterListParen(name): | 8 def _FindParameterListParen(name): |
| 9 """Finds index of the "(" that denotes the start of a paremeter list.""" | 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 | 10 # This loops from left-to-right, but the only reason (I think) that this |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 template_balance_count += 1 | 36 template_balance_count += 1 |
| 37 | 37 |
| 38 paren_balance_count += ( | 38 paren_balance_count += ( |
| 39 name.count('(', start_idx, idx) - name.count(')', start_idx, idx)) | 39 name.count('(', start_idx, idx) - name.count(')', start_idx, idx)) |
| 40 if template_balance_count == 0 and paren_balance_count == 0: | 40 if template_balance_count == 0 and paren_balance_count == 0: |
| 41 # Special case: skip "(anonymous namespace)". | 41 # Special case: skip "(anonymous namespace)". |
| 42 if -1 != name.find('(anonymous namespace)', idx, idx + 21): | 42 if -1 != name.find('(anonymous namespace)', idx, idx + 21): |
| 43 start_idx = idx + 21 | 43 start_idx = idx + 21 |
| 44 continue | 44 continue |
| 45 # Special case: skip "decltype (...)" | 45 # Special case: skip "decltype (...)" |
| 46 if name[idx - 1] != ' ': | 46 # Special case: skip "{lambda(PaintOp*)#63}" |
| 47 if name[idx - 1] != ' ' and name[idx - 7:idx] != '{lambda': |
| 47 return idx | 48 return idx |
| 48 start_idx = idx + 1 | 49 start_idx = idx + 1 |
| 49 paren_balance_count += 1 | 50 paren_balance_count += 1 |
| 50 | 51 |
| 51 | 52 |
| 52 def _FindLastCharOutsideOfBrackets(name, target_char, prev_idx=None): | 53 def _FindLastCharOutsideOfBrackets(name, target_char, prev_idx=None): |
| 53 """Returns the last index of |target_char| that is not within ()s nor <>s.""" | 54 """Returns the last index of |target_char| that is not within ()s nor <>s.""" |
| 54 paren_balance_count = 0 | 55 paren_balance_count = 0 |
| 55 template_balance_count = 0 | 56 template_balance_count = 0 |
| 56 while True: | 57 while True: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 78 space_idx = _FindLastCharOutsideOfBrackets(name, ' ', space_idx) | 79 space_idx = _FindLastCharOutsideOfBrackets(name, ' ', space_idx) |
| 79 # Special case: "operator new", and "operator<< <template>". | 80 # Special case: "operator new", and "operator<< <template>". |
| 80 if -1 == space_idx or ( | 81 if -1 == space_idx or ( |
| 81 -1 == name.find('operator', space_idx - 8, space_idx) and | 82 -1 == name.find('operator', space_idx - 8, space_idx) and |
| 82 -1 == name.find('operator<<', space_idx - 10, space_idx)): | 83 -1 == name.find('operator<<', space_idx - 10, space_idx)): |
| 83 break | 84 break |
| 84 space_idx -= 8 | 85 space_idx -= 8 |
| 85 return space_idx | 86 return space_idx |
| 86 | 87 |
| 87 | 88 |
| 89 def _NormalizeTopLevelLambda(name, space_idx, left_paren_idx): |
| 90 # cc::{lambda(PaintOp*)#63}::_FUN() -> cc:{lambda#63}() |
| 91 paren_idx = name.index('(', space_idx + 1) |
| 92 hash_idx = name.rindex('#', paren_idx) |
| 93 return (name[:paren_idx] + name[hash_idx:left_paren_idx - 6] + |
| 94 name[left_paren_idx:]) |
| 95 |
| 96 |
| 88 def Parse(name): | 97 def Parse(name): |
| 89 """Extracts a function name from a function signature. | 98 """Extracts a function name from a function signature. |
| 90 | 99 |
| 91 See unit tests for example signatures. | 100 See unit tests for example signatures. |
| 92 | 101 |
| 93 Returns: | 102 Returns: |
| 94 A tuple of (name_without_return_type, name_without_return_type_and_params). | 103 A tuple of (name_without_return_type, name_without_return_type_and_params). |
| 95 """ | 104 """ |
| 96 left_paren_idx = _FindParameterListParen(name) | 105 left_paren_idx = _FindParameterListParen(name) |
| 97 | 106 |
| 107 full_name = name |
| 98 if left_paren_idx > 0: | 108 if left_paren_idx > 0: |
| 99 right_paren_idx = name.rindex(')') | 109 right_paren_idx = name.rindex(')') |
| 100 assert right_paren_idx > left_paren_idx | 110 assert right_paren_idx > left_paren_idx |
| 101 space_idx = _FindReturnValueSpace(name, left_paren_idx) | 111 space_idx = _FindReturnValueSpace(name, left_paren_idx) |
| 102 return (name[space_idx + 1:], | 112 name_without_attrib = name[space_idx + 1:left_paren_idx] |
| 103 name[space_idx + 1:left_paren_idx] + name[right_paren_idx + 1:]) | 113 # Special case for top-level lamdas. |
| 104 return name, name | 114 if name_without_attrib.endswith('}::_FUN'): |
| 115 # Don't use name_without_attrib in here since prior _idx will be off if |
| 116 # there was a return value. |
| 117 name = _NormalizeTopLevelLambda(name, space_idx, left_paren_idx) |
| 118 return Parse(name) |
| 119 |
| 120 full_name = name[space_idx + 1:] |
| 121 name = name_without_attrib + name[right_paren_idx + 1:] |
| 122 |
| 123 return full_name, name |
| OLD | NEW |