lizard 1.17.19__py2.py3-none-any.whl → 1.17.21__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lizard
3
- Version: 1.17.19
3
+ Version: 1.17.21
4
4
  Summary: A code analyzer without caring the C/C++ header files. It works with Java, C/C++, JavaScript, Python, Ruby, Swift, Objective C. Metrics includes cyclomatic complexity number etc.
5
5
  Home-page: http://www.lizard.ws
6
6
  Download-URL: https://pypi.python.org/lizard/
@@ -72,6 +72,7 @@ A list of supported languages:
72
72
  - Solidity
73
73
  - Erlang
74
74
  - Zig
75
+ - Perl
75
76
 
76
77
  By default lizard will search for any source code that it knows and mix
77
78
  all the results together. This might not be what you want. You can use
@@ -25,9 +25,9 @@ lizard_ext/lizardns.py,sha256=8pztUoRS_UWN24MawwxeHEJgYh49id5PWODUBb6O72U,4184
25
25
  lizard_ext/lizardoutside.py,sha256=FGm2tbBZ17-2OCgmQlD-vobUCfQKb0FAygf86eM3xuM,336
26
26
  lizard_ext/lizardstatementcount.py,sha256=xYk6ixSIItSE1BWQXzrWmduFgGhA3VR817SNKLffyVQ,1182
27
27
  lizard_ext/lizardwordcount.py,sha256=2QYXD7-AtkkgAbi9VSidunMbSsGQ7MKYb6IT-bS-cok,7575
28
- lizard_ext/version.py,sha256=oguHTKBWAqPz-fmtCOkqHzNbUNECBfUhm0EIg6y01RI,182
28
+ lizard_ext/version.py,sha256=3mpAZCQFxtZ-yEx47ZY238MZafb6rPxy9lZff5hymyA,182
29
29
  lizard_ext/xmloutput.py,sha256=-cbh0he4O_X-wX56gkv9AnSPNN0qvR7FACqlBeezUS4,5609
30
- lizard_languages/__init__.py,sha256=2mvrPWMJVCq981kMjoAPEi2O07C8vo-vUWOG_wp7vKQ,1473
30
+ lizard_languages/__init__.py,sha256=ArNmUrVSU6HFxhDka1-vWMZpVIM39P-gqv6BoOLNMV8,1522
31
31
  lizard_languages/clike.py,sha256=INd5tkvwEVZm7dx2yHG2OIFHZn7JzQGmnT9WQNFZ2XU,11110
32
32
  lizard_languages/code_reader.py,sha256=P0PkE4QZBWOEj6cFHA4hj3hcLZLcGnqH31EmtltxlaE,6240
33
33
  lizard_languages/csharp.py,sha256=EfFAIOIcJXUUhXTlZApXGSlzG34NZvHM9OSe6m7hpv0,2141
@@ -36,14 +36,15 @@ lizard_languages/fortran.py,sha256=KATDsnfjob5W3579A_VxbwrbTkK7Rx3p0eXdBgjx25I,8
36
36
  lizard_languages/gdscript.py,sha256=KwlGoODilQnFgXvODpq_XlA6fV3hGbN9fd7bsiEUn78,637
37
37
  lizard_languages/go.py,sha256=iU2wZ0Iuo4OifscZhoHS_jDbdGYxquocqmvYX0l9MnE,1358
38
38
  lizard_languages/golike.py,sha256=vRIfjTVvc0VmJf27lTOLht55ZF1AQ9wn0Fvu-9WabWk,2858
39
- lizard_languages/java.py,sha256=J8FYdgzGK5ojmfxSfMfWopKGTLsHwJ123XOOZCfi51c,4957
39
+ lizard_languages/java.py,sha256=c1rd0PN4iIrYHPLTFW67YsBX6pizsrJma3tfCDj9B2Q,4936
40
40
  lizard_languages/javascript.py,sha256=qqxocZbZ6ivchhswRBBSjEJKiTClnm9ScOy4nlX4JKA,318
41
- lizard_languages/js_style_language_states.py,sha256=Ie0eA15rd0gfahdNzUlSkQa-o_j5idTIB82JU32c378,4165
41
+ lizard_languages/js_style_language_states.py,sha256=AdiehzSziZIbuWMomYmchNsJr7ZqtxN6l29osj3SA3A,4431
42
42
  lizard_languages/js_style_regex_expression.py,sha256=Xgyogch4xElYtCG4EnBKvalHTl3tjRPcIIcIQRRd61I,1970
43
- lizard_languages/jsx.py,sha256=KA9tDZ8kRSey8RefeC6DJg36yLBi6AEbm5JmVB-TQMU,3951
43
+ lizard_languages/jsx.py,sha256=DMagQSEvXZwy9AUj8B2l39PqgcAoZntAmEm67IKF7iM,8890
44
44
  lizard_languages/kotlin.py,sha256=v_o2orEzA5gB9vM_0h-E4QXjrc5Yum-0K6W6_laOThc,2844
45
45
  lizard_languages/lua.py,sha256=3nqBcunBzJrhv4Iqaf8xvbyqxZy3aSxJ-IiHimHFlac,1573
46
46
  lizard_languages/objc.py,sha256=2a1teLdaXZBtCeFiIZer1j_sVx9LZ1CbF2XfnqlvLmk,2319
47
+ lizard_languages/perl.py,sha256=bSBolem2X6TjINz7pJGO_WhQxc-pAeiun0Q3RDeUOkY,3367
47
48
  lizard_languages/php.py,sha256=8OufyR2TIWyf3bXuTmp37Vwf_tEPF4YV5M3i5_jnguA,1377
48
49
  lizard_languages/python.py,sha256=1e0dKbl82z-i_5dswkKaFIV5WuQDKztPHh9UNmSTLyE,3848
49
50
  lizard_languages/ruby.py,sha256=HL1ZckeuUUJU3QSVAOPsG_Zsl0C6X2PX5_VaWqclzkM,2277
@@ -54,14 +55,14 @@ lizard_languages/script_language.py,sha256=UUO3Wjkoa-ZqwwvcwvhOr5tg1rVavcrEYx3dN
54
55
  lizard_languages/solidity.py,sha256=Z0GD7U5bI5eUikdy7m_iKWeFD5yXRYq4r3zycscOhJQ,553
55
56
  lizard_languages/swift.py,sha256=p8S2OAkQOx9YQ02yhoVXFkr7pMqUH1Nb3RVXPHRU_9M,2450
56
57
  lizard_languages/tnsdl.py,sha256=pGcalA_lHY362v2wwPS86seYBOOBBjvmU6vd4Yy3A9g,2803
57
- lizard_languages/tsx.py,sha256=pzScdziLmFkD1c0LfwUNyC64C0HFmqt16QtsANu0UJ8,639
58
+ lizard_languages/tsx.py,sha256=4fhi3sUnvjU4XfGaFUEGOdAYOx6ThGpIMOIS9VSL6cQ,1160
58
59
  lizard_languages/ttcn.py,sha256=ygjw_raBmPF-4mgoM8m6CAdyEMpTI-n1kZJK1RL4Vxo,2131
59
- lizard_languages/typescript.py,sha256=jXN3q01g46tWVb9jXjsmwypcAXx0t-vpK3UFQ-SHw9U,3645
60
+ lizard_languages/typescript.py,sha256=P_rphg5AXJAk9QetmvVKc2911ilPmiRa0Qa5fHWleJg,3829
60
61
  lizard_languages/vue.py,sha256=KXUBUo2R1zNF8Pffrz_KsQEN44m5XFRMoGXylxKUeT0,1038
61
62
  lizard_languages/zig.py,sha256=NX1iyBstBuJFeAGBOAIaRfrmeBREne2HX6Pt4fXZZTQ,586
62
- lizard-1.17.19.dist-info/LICENSE.txt,sha256=05ZjgQ8Cl1dD9p0BhW-Txzkc5rhCogGJVEuf1GT2Y_M,1303
63
- lizard-1.17.19.dist-info/METADATA,sha256=yX7xfYELh1ZHKXiGt2mNF9ABjGhiU6SDph-3nvuODZU,15745
64
- lizard-1.17.19.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
65
- lizard-1.17.19.dist-info/entry_points.txt,sha256=ZBqPhu-J3NoGGW5vn2Gfyoo0vdVlgBgM-wlNm0SGYUQ,39
66
- lizard-1.17.19.dist-info/top_level.txt,sha256=5NTrTaOLhHuTzXaGcZPKfuaOgUv7WafNGe0Zl5aycpg,35
67
- lizard-1.17.19.dist-info/RECORD,,
63
+ lizard-1.17.21.dist-info/LICENSE.txt,sha256=05ZjgQ8Cl1dD9p0BhW-Txzkc5rhCogGJVEuf1GT2Y_M,1303
64
+ lizard-1.17.21.dist-info/METADATA,sha256=JSVKupJ-s_F1BqRK88FS30969tOc9TaHxPaPlZzXdzo,15753
65
+ lizard-1.17.21.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
66
+ lizard-1.17.21.dist-info/entry_points.txt,sha256=ZBqPhu-J3NoGGW5vn2Gfyoo0vdVlgBgM-wlNm0SGYUQ,39
67
+ lizard-1.17.21.dist-info/top_level.txt,sha256=5NTrTaOLhHuTzXaGcZPKfuaOgUv7WafNGe0Zl5aycpg,35
68
+ lizard-1.17.21.dist-info/RECORD,,
lizard_ext/version.py CHANGED
@@ -3,4 +3,4 @@
3
3
  #
4
4
  # pylint: disable=missing-docstring,invalid-name
5
5
 
6
- version = "1.17.19"
6
+ version = "1.17.21"
@@ -24,6 +24,7 @@ from .solidity import SolidityReader
24
24
  from .jsx import JSXReader
25
25
  from .tsx import TSXReader
26
26
  from .vue import VueReader
27
+ from .perl import PerlReader
27
28
 
28
29
 
29
30
  def languages():
@@ -52,6 +53,7 @@ def languages():
52
53
  JSXReader,
53
54
  TSXReader,
54
55
  VueReader,
56
+ PerlReader,
55
57
  ]
56
58
 
57
59
 
lizard_languages/java.py CHANGED
@@ -123,7 +123,6 @@ class JavaFunctionBodyStates(JavaStates):
123
123
  if token == "(":
124
124
  self.sub_state(JavaFunctionBodyStates(self.context), None, token)
125
125
  return
126
- print(token)
127
126
  if token == "{":
128
127
  def callback():
129
128
  self.next(self._state_global)
@@ -34,6 +34,8 @@ class JavaScriptStyleLanguageStates(CodeStateMachine): # pylint: disable=R0903
34
34
  elif token in ('else', 'do', 'try', 'final'):
35
35
  self.next(self._expecting_statement_or_block)
36
36
  elif token in ('=>',):
37
+ if self.function_name:
38
+ self._push_function_to_stack()
37
39
  self._state = self._arrow_function
38
40
  elif token == '=':
39
41
  self.function_name = self.last_tokens
@@ -100,7 +102,13 @@ class JavaScriptStyleLanguageStates(CodeStateMachine): # pylint: disable=R0903
100
102
 
101
103
  def _arrow_function(self, token):
102
104
  self._push_function_to_stack()
103
- self.next(self._state_global, token)
105
+ # Handle arrow function body
106
+ if token == '{':
107
+ # Block body
108
+ self.next(self._state_global, token)
109
+ else:
110
+ # Expression body
111
+ self.next(self._state_global, token)
104
112
 
105
113
  def _function(self, token):
106
114
  if token == '*':
lizard_languages/jsx.py CHANGED
@@ -6,6 +6,7 @@ from .javascript import JavaScriptReader
6
6
  from .typescript import JSTokenizer, Tokenizer
7
7
  from .code_reader import CodeReader
8
8
  from .js_style_regex_expression import js_style_regex_expression
9
+ from .js_style_language_states import JavaScriptStyleLanguageStates
9
10
 
10
11
 
11
12
  class TSXTokenizer(JSTokenizer):
@@ -17,6 +18,11 @@ class TSXTokenizer(JSTokenizer):
17
18
  from .jsx import XMLTagWithAttrTokenizer # Import only when needed
18
19
  self.sub_tokenizer = XMLTagWithAttrTokenizer()
19
20
  return
21
+
22
+ if token == "=>":
23
+ # Special handling for arrow functions
24
+ yield token
25
+ return
20
26
 
21
27
  for tok in super().process_token(token):
22
28
  yield tok
@@ -30,6 +36,7 @@ class JSXMixin:
30
36
  addition = addition +\
31
37
  r"|(?:\$\w+)" + \
32
38
  r"|(?:\<\/\w+\>)" + \
39
+ r"|(?:=>)" + \
33
40
  r"|`.*?`"
34
41
  js_tokenizer = TSXTokenizer()
35
42
  for token in CodeReader.generate_tokens(
@@ -41,13 +48,94 @@ class JSXMixin:
41
48
  if token == '<':
42
49
  self.next(self._expecting_jsx)
43
50
  return
51
+ if token == '=>':
52
+ # Handle arrow functions in JSX attributes
53
+ self._handle_arrow_function()
54
+ return
44
55
  super()._expecting_func_opening_bracket(token)
45
56
 
57
+ def _handle_arrow_function(self):
58
+ # Process arrow function in JSX context
59
+ self.context.add_to_long_function_name(" => ")
60
+
61
+ # Store the current function
62
+ current_function = self.context.current_function
63
+
64
+ # Create a new anonymous function
65
+ self.context.restart_new_function('(anonymous)')
66
+
67
+ # Set up for the arrow function body
68
+ def callback():
69
+ # Return to the original function when done
70
+ self.context.current_function = current_function
71
+
72
+ self.sub_state(self.__class__(self.context), callback)
73
+
74
+ def _expecting_arrow_function_body(self, token):
75
+ if token == '{':
76
+ # Arrow function with block body
77
+ self.next(self._function_body)
78
+ else:
79
+ # Arrow function with expression body
80
+ self.next(self._expecting_func_opening_bracket)
81
+
82
+ def _function_body(self, token):
83
+ if token == '}':
84
+ # End of arrow function body
85
+ self.context.end_of_function()
86
+ self.next(self._expecting_func_opening_bracket)
87
+
46
88
  def _expecting_jsx(self, token):
47
89
  if token == '>':
48
90
  self.next(self._expecting_func_opening_bracket)
49
91
 
50
92
 
93
+ class JSXJavaScriptStyleLanguageStates(JavaScriptStyleLanguageStates):
94
+ def __init__(self, context):
95
+ super(JSXJavaScriptStyleLanguageStates, self).__init__(context)
96
+
97
+ def _state_global(self, token):
98
+ if token == 'const' or token == 'let' or token == 'var':
99
+ # Remember that we're in a variable declaration
100
+ self.in_variable_declaration = True
101
+ super()._state_global(token)
102
+ return
103
+
104
+ if hasattr(self, 'in_variable_declaration') and self.in_variable_declaration:
105
+ if token == '=':
106
+ # We're in a variable assignment
107
+ self.function_name = self.last_tokens
108
+ super()._state_global(token)
109
+ return
110
+ elif token == '=>':
111
+ # We're in an arrow function with a variable assignment
112
+ self._push_function_to_stack()
113
+ self._state = self._arrow_function
114
+ return
115
+ elif token == ';' or self.context.newline:
116
+ # End of variable declaration
117
+ self.in_variable_declaration = False
118
+
119
+ super()._state_global(token)
120
+
121
+ def _expecting_func_opening_bracket(self, token):
122
+ if token == ':':
123
+ # Handle type annotations like TypeScript does
124
+ self._consume_type_annotation()
125
+ return
126
+ super()._expecting_func_opening_bracket(token)
127
+
128
+ def _consume_type_annotation(self):
129
+ # Skip over type annotations (simplified version of TypeScript's behavior)
130
+ def skip_until_terminator(token):
131
+ if token in ['{', '=', ';', ')', '(', '=>']:
132
+ self.next(self._state_global, token)
133
+ return True
134
+ return False
135
+
136
+ self.next(skip_until_terminator)
137
+
138
+
51
139
  class JSXReader(JavaScriptReader, JSXMixin):
52
140
  # pylint: disable=R0903
53
141
 
@@ -57,8 +145,17 @@ class JSXReader(JavaScriptReader, JSXMixin):
57
145
  @staticmethod
58
146
  @js_style_regex_expression
59
147
  def generate_tokens(source_code, addition='', token_class=None):
148
+ # Add support for JSX syntax patterns
149
+ addition = addition + \
150
+ r"|(?:<[A-Za-z][A-Za-z0-9]*(?:\.[A-Za-z][A-Za-z0-9]*)*>)" + \
151
+ r"|(?:<\/[A-Za-z][A-Za-z0-9]*(?:\.[A-Za-z][A-Za-z0-9]*)*>)"
60
152
  return JSXMixin.generate_tokens(source_code, addition, token_class)
61
153
 
154
+ def __init__(self, context):
155
+ super(JSXReader, self).__init__(context)
156
+ # Use our custom JavaScriptStyleLanguageStates subclass
157
+ self.parallel_states = [JSXJavaScriptStyleLanguageStates(context)]
158
+
62
159
 
63
160
  class XMLTagWithAttrTokenizer(Tokenizer):
64
161
  def __init__(self):
@@ -66,6 +163,8 @@ class XMLTagWithAttrTokenizer(Tokenizer):
66
163
  self.tag = None
67
164
  self.state = self._global_state
68
165
  self.cache = ['<']
166
+ self.brace_count = 0 # Track nested braces for complex expressions
167
+ self.arrow_function_detected = False # Track if we've detected an arrow function
69
168
 
70
169
  def process_token(self, token):
71
170
  self.cache.append(token)
@@ -115,9 +214,34 @@ class XMLTagWithAttrTokenizer(Tokenizer):
115
214
  if token[0] in "'\"":
116
215
  self.state = self._after_tag
117
216
  elif token == "{":
118
- self.cache.append("}")
217
+ self.brace_count = 1 # Start counting braces
218
+ self.state = self._jsx_expression
219
+ # Don't add the closing brace automatically
220
+ # self.cache.append("}")
119
221
  self.sub_tokenizer = TSXTokenizer()
120
- self.state = self._after_tag
222
+
223
+ def _jsx_expression(self, token):
224
+ # Handle nested braces in expressions
225
+ if token == "{":
226
+ self.brace_count += 1
227
+ elif token == "}":
228
+ self.brace_count -= 1
229
+ if self.brace_count == 0:
230
+ # We've found the matching closing brace
231
+ self.state = self._after_tag
232
+ return
233
+
234
+ # Handle arrow functions in JSX attributes
235
+ if token == "=>":
236
+ self.arrow_function_detected = True
237
+ # Explicitly yield the arrow token to ensure it's processed
238
+ return ["=>"]
239
+
240
+ # Handle type annotations in JSX attributes
241
+ if token == "<":
242
+ # This might be a TypeScript generic type annotation
243
+ # We'll continue in the current state and let the tokenizer handle it
244
+ pass
121
245
 
122
246
  def _body(self, token):
123
247
  if token == "<":
@@ -0,0 +1,103 @@
1
+ '''
2
+ Language parser for Perl
3
+ '''
4
+
5
+ from .code_reader import CodeReader, CodeStateMachine
6
+ from .script_language import ScriptLanguageMixIn
7
+
8
+
9
+ class PerlCommentsMixin(object):
10
+ @staticmethod
11
+ def get_comment_from_token(token):
12
+ if token.startswith('#'):
13
+ return token # Return the entire comment including #
14
+ return None
15
+
16
+
17
+ class PerlReader(CodeReader, ScriptLanguageMixIn):
18
+ # pylint: disable=R0903
19
+
20
+ ext = ['pl', 'pm']
21
+ language_names = ['perl']
22
+ _conditions = set(['if', 'elsif', 'unless', 'while', 'until', 'for', 'foreach', '&&', '||', '?', 'when'])
23
+
24
+ def __init__(self, context):
25
+ super(PerlReader, self).__init__(context)
26
+ self.parallel_states = [PerlStates(context)]
27
+
28
+ def preprocess(self, tokens):
29
+ comment = None
30
+ for token in tokens:
31
+ if comment is not None:
32
+ if token == '\n':
33
+ yield comment
34
+ comment = None
35
+ yield token
36
+ else:
37
+ comment += token
38
+ elif token == '#':
39
+ comment = token
40
+ else:
41
+ yield token
42
+ if comment is not None:
43
+ yield comment
44
+
45
+ def _state(self, token):
46
+ current_state = self.parallel_states[-1]
47
+ if token == '\n':
48
+ return
49
+ return current_state.state(token)
50
+
51
+ @staticmethod
52
+ def get_comment_from_token(token):
53
+ if token.startswith('#'):
54
+ # For forgiveness comments, return the entire comment
55
+ stripped = token.lstrip('#').strip()
56
+ if stripped.startswith('lizard forgives') or stripped.startswith('#lizard forgives'):
57
+ return '#lizard forgives' # Return standardized forgiveness comment
58
+ return stripped # Return the stripped comment for other cases
59
+ return None
60
+
61
+ @staticmethod
62
+ def generate_tokens(source_code, addition='', token_class=None):
63
+ return ScriptLanguageMixIn.generate_common_tokens(source_code, addition, token_class)
64
+
65
+
66
+ class PerlStates(CodeStateMachine):
67
+ _conditions = set(['if', 'elsif', 'unless', 'while', 'until', 'for', 'foreach'])
68
+
69
+ def __init__(self, context):
70
+ super(PerlStates, self).__init__(context)
71
+ self.function_name = ''
72
+ self.brace_count = 0
73
+ self._state = self._state_global
74
+
75
+ def _state_global(self, token):
76
+ if token == 'sub':
77
+ self.function_name = ''
78
+ self.next(self._state_function_dec)
79
+ elif token == '{':
80
+ self.brace_count += 1
81
+ elif token == '}':
82
+ self.brace_count -= 1
83
+
84
+ def _state_function_dec(self, token):
85
+ if token == '{':
86
+ self.brace_count = 1
87
+ if self.function_name:
88
+ self.context.try_new_function(self.function_name)
89
+ self.context.confirm_new_function()
90
+ self.next(self._state_function_body)
91
+ elif token == ';':
92
+ self.next(self._state_global)
93
+ elif not token.isspace():
94
+ self.function_name = token
95
+
96
+ def _state_function_body(self, token):
97
+ if token == '{':
98
+ self.brace_count += 1
99
+ elif token == '}':
100
+ self.brace_count -= 1
101
+ if self.brace_count == 0:
102
+ self.context.end_of_function()
103
+ self.next(self._state_global)
lizard_languages/tsx.py CHANGED
@@ -16,8 +16,19 @@ class TSXReader(TypeScriptReader, JSXMixin):
16
16
  @staticmethod
17
17
  @js_style_regex_expression
18
18
  def generate_tokens(source_code, addition='', token_class=None):
19
+ # Add support for TypeScript type annotations in JSX
20
+ addition = addition + \
21
+ r"|(?:<[A-Za-z][A-Za-z0-9]*(?:\.[A-Za-z][A-Za-z0-9]*)*>)" + \
22
+ r"|(?:<\/[A-Za-z][A-Za-z0-9]*(?:\.[A-Za-z][A-Za-z0-9]*)*>)"
19
23
  return JSXMixin.generate_tokens(source_code, addition, token_class)
20
24
 
21
25
  def __init__(self, context):
22
26
  super(TSXReader, self).__init__(context)
23
27
  # No need for parallel states since JSX handling is in the mixin
28
+
29
+ def _expecting_func_opening_bracket(self, token):
30
+ # Handle TypeScript arrow functions with type annotations in JSX attributes
31
+ if token == ':':
32
+ self._consume_type_annotation()
33
+ return
34
+ super()._expecting_func_opening_bracket(token)
@@ -111,13 +111,13 @@ class TypeScriptTypeAnnotationStates(CodeStateMachine):
111
111
  self.next(self._state_simple_type, token)
112
112
 
113
113
  def _state_simple_type(self, token):
114
- print(token)
115
114
  if token == '<':
116
- print(token)
117
115
  self.next(self._state_generic_type, token)
118
116
  elif token in '{=;':
119
117
  self.saved_token = token
120
118
  self.statemachine_return()
119
+ elif token == '(':
120
+ self.next(self._function_type_annotation, token)
121
121
 
122
122
  @CodeStateMachine.read_inside_brackets_then("{}")
123
123
  def _inline_type_annotation(self, _):
@@ -126,3 +126,7 @@ class TypeScriptTypeAnnotationStates(CodeStateMachine):
126
126
  @CodeStateMachine.read_inside_brackets_then("<>")
127
127
  def _state_generic_type(self, token):
128
128
  self.statemachine_return()
129
+
130
+ @CodeStateMachine.read_inside_brackets_then("()")
131
+ def _function_type_annotation(self, _):
132
+ self.statemachine_return()