Whole file
terryyin/lizard
The author described this change as “fix(objc): handle nested parens in block / function-pointer param types”. It counts as a record because the checks below fail on the code as it stood at 06284ec87 and pass on 6001e5462, with nothing else changed between the two runs.
Projectterryyin/lizard
Fix saved2026-06-02
Sharing licenceMIT · LICENSE.txt
Change size+15 −2
What the code was meant to do, written into the code itself as a save note
fix(objc): handle nested parens in block / function-pointer param types
The change
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | class ObjCStates(CLikeStates): # pylint: disable=R0903 | |
| 26 | + | def __init__(self, context): | |
| 27 | + | super(ObjCStates, self).__init__(context) | |
| 28 | + | self._objc_param_paren_depth = 0 | |
| 29 | + | ||
| 26 | 30 | def _state_global(self, token): | |
| 27 | 31 | super(ObjCStates, self)._state_global(token) | |
| 28 | 32 | if token == 'typedef': | |
| ⋯ | |||
| 50 | 54 | ||
| 51 | 55 | def _state_objc_dec(self, token): | |
| 52 | 56 | if token == '(': | |
| 57 | + | self._objc_param_paren_depth = 0 | |
| 53 | 58 | self._state = self._state_objc_param_type | |
| 54 | 59 | self.context.add_to_long_function_name(token) | |
| 55 | 60 | elif token == ',': | |
| ⋯ | |||
| 61 | 66 | self.context.add_to_function_name(" " + token) | |
| 62 | 67 | ||
| 63 | 68 | def _state_objc_param_type(self, token): | |
| 64 | - | if token == ')': | |
| 65 | - | self._state = self._state_objc_param | |
| 69 | + | # A block / function-pointer param type, e.g. (void (^)(int)), nests | |
| 70 | + | # parentheses; balance them so the type ends at its matching ')' | |
| 71 | + | # rather than the first inner one (issue #365). | |
| 72 | + | if token == '(': | |
| 73 | + | self._objc_param_paren_depth += 1 | |
| 74 | + | elif token == ')': | |
| 75 | + | if self._objc_param_paren_depth > 0: | |
| 76 | + | self._objc_param_paren_depth -= 1 | |
| 77 | + | else: | |
| 78 | + | self._state = self._state_objc_param | |
| 66 | 79 | self.context.add_to_long_function_name(" " + token) | |
| 67 | 80 | ||
| 68 | 81 | def _state_objc_param(self, _): | |
The check that tells the two apart
fail→pass·test/test_languages/testObjC.py::Test_objc_lizard::test_objc_method_with_block_param
fail→pass·test/test_languages/testObjC.py::Test_objc_lizard::test_objc_method_with_function_pointer_param
Check file test/test_languages/testObjC.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.
Origin and history
The code before it06284ec87c1966fee4ddbf3f068ccf89b987b0f8
Broken version dated2026-06-02
Modulelizard_languages.objc
Units changedObjCStates
Fingerprint662c4f60a7f94357
Checked2026-08-18 by goldset/0.1
Every field above is generated by our program. None of it is written by hand.
Other bugs found in terryyin/lizard
- 2026-08-08fix(java): do not report control structures as methods
- 2026-07-02HalsteadClassifier
- 2026-07-02fix(csv): emit columns for extensions with multiple FUNCTION_INFO fields
- 2026-06-15fix(golike): register generic functions with [...] type params
- 2026-06-15fix(java): enhance parsing of generic and qualified type names in anonymous classes
- 2026-06-11fix(script): stop a '#' comment continuing past a trailing backslash (#317)