lizard 1.17.18__tar.gz → 1.17.20__tar.gz

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.
Files changed (99) hide show
  1. {lizard-1.17.18 → lizard-1.17.20}/PKG-INFO +1 -1
  2. {lizard-1.17.18 → lizard-1.17.20}/lizard.egg-info/PKG-INFO +1 -1
  3. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/version.py +1 -1
  4. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/java.py +1 -1
  5. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/js_style_language_states.py +9 -1
  6. lizard-1.17.20/lizard_languages/jsx.py +265 -0
  7. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/tsx.py +11 -0
  8. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/typescript.py +6 -2
  9. lizard-1.17.18/lizard_languages/jsx.py +0 -141
  10. {lizard-1.17.18 → lizard-1.17.20}/LICENSE.txt +0 -0
  11. {lizard-1.17.18 → lizard-1.17.20}/README.rst +0 -0
  12. {lizard-1.17.18 → lizard-1.17.20}/lizard.egg-info/SOURCES.txt +0 -0
  13. {lizard-1.17.18 → lizard-1.17.20}/lizard.egg-info/dependency_links.txt +0 -0
  14. {lizard-1.17.18 → lizard-1.17.20}/lizard.egg-info/entry_points.txt +0 -0
  15. {lizard-1.17.18 → lizard-1.17.20}/lizard.egg-info/requires.txt +0 -0
  16. {lizard-1.17.18 → lizard-1.17.20}/lizard.egg-info/top_level.txt +0 -0
  17. {lizard-1.17.18 → lizard-1.17.20}/lizard.py +0 -0
  18. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/__init__.py +0 -0
  19. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/auto_open.py +0 -0
  20. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/csvoutput.py +0 -0
  21. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/default_ordered_dict.py +0 -0
  22. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/extension_base.py +0 -0
  23. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/htmloutput.py +0 -0
  24. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/keywords.py +0 -0
  25. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardboolcount.py +0 -0
  26. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardcomplextags.py +0 -0
  27. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardcpre.py +0 -0
  28. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizarddependencycount.py +0 -0
  29. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizarddumpcomments.py +0 -0
  30. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardduplicate.py +0 -0
  31. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardduplicated_param_list.py +0 -0
  32. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardexitcount.py +0 -0
  33. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardgotocount.py +0 -0
  34. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardignoreassert.py +0 -0
  35. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardio.py +0 -0
  36. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardmccabe.py +0 -0
  37. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardmodified.py +0 -0
  38. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardnd.py +0 -0
  39. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardnonstrict.py +0 -0
  40. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardns.py +0 -0
  41. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardoutside.py +0 -0
  42. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardstatementcount.py +0 -0
  43. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/lizardwordcount.py +0 -0
  44. {lizard-1.17.18 → lizard-1.17.20}/lizard_ext/xmloutput.py +0 -0
  45. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/__init__.py +0 -0
  46. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/clike.py +0 -0
  47. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/code_reader.py +0 -0
  48. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/csharp.py +0 -0
  49. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/erlang.py +0 -0
  50. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/fortran.py +0 -0
  51. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/gdscript.py +0 -0
  52. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/go.py +0 -0
  53. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/golike.py +0 -0
  54. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/javascript.py +0 -0
  55. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/js_style_regex_expression.py +0 -0
  56. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/kotlin.py +0 -0
  57. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/lua.py +0 -0
  58. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/objc.py +0 -0
  59. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/php.py +0 -0
  60. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/python.py +0 -0
  61. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/ruby.py +0 -0
  62. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/rubylike.py +0 -0
  63. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/rust.py +0 -0
  64. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/scala.py +0 -0
  65. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/script_language.py +0 -0
  66. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/solidity.py +0 -0
  67. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/swift.py +0 -0
  68. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/tnsdl.py +0 -0
  69. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/ttcn.py +0 -0
  70. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/vue.py +0 -0
  71. {lizard-1.17.18 → lizard-1.17.20}/lizard_languages/zig.py +0 -0
  72. {lizard-1.17.18 → lizard-1.17.20}/setup.cfg +0 -0
  73. {lizard-1.17.18 → lizard-1.17.20}/setup.py +0 -0
  74. {lizard-1.17.18 → lizard-1.17.20}/test/testApplication.py +0 -0
  75. {lizard-1.17.18 → lizard-1.17.20}/test/testAssertionExtension.py +0 -0
  76. {lizard-1.17.18 → lizard-1.17.20}/test/testBasicFunctionInfo.py +0 -0
  77. {lizard-1.17.18 → lizard-1.17.20}/test/testCOutsideComplexity.py +0 -0
  78. {lizard-1.17.18 → lizard-1.17.20}/test/testCPreprocessorExtension.py +0 -0
  79. {lizard-1.17.18 → lizard-1.17.20}/test/testCommentOptions.py +0 -0
  80. {lizard-1.17.18 → lizard-1.17.20}/test/testCyclomaticComplexity.py +0 -0
  81. {lizard-1.17.18 → lizard-1.17.20}/test/testExtension.py +0 -0
  82. {lizard-1.17.18 → lizard-1.17.20}/test/testFilesFilter.py +0 -0
  83. {lizard-1.17.18 → lizard-1.17.20}/test/testFunctionDependencyCount.py +0 -0
  84. {lizard-1.17.18 → lizard-1.17.20}/test/testFunctionExitCount.py +0 -0
  85. {lizard-1.17.18 → lizard-1.17.20}/test/testFunctionGotoCount.py +0 -0
  86. {lizard-1.17.18 → lizard-1.17.20}/test/testFunctionStatementCount.py +0 -0
  87. {lizard-1.17.18 → lizard-1.17.20}/test/testHelpers.py +0 -0
  88. {lizard-1.17.18 → lizard-1.17.20}/test/testLanguages.py +0 -0
  89. {lizard-1.17.18 → lizard-1.17.20}/test/testMcCabe.py +0 -0
  90. {lizard-1.17.18 → lizard-1.17.20}/test/testNestedStructures.py +0 -0
  91. {lizard-1.17.18 → lizard-1.17.20}/test/testNestingDepth.py +0 -0
  92. {lizard-1.17.18 → lizard-1.17.20}/test/testOutput.py +0 -0
  93. {lizard-1.17.18 → lizard-1.17.20}/test/testOutputCSV.py +0 -0
  94. {lizard-1.17.18 → lizard-1.17.20}/test/testOutputFile.py +0 -0
  95. {lizard-1.17.18 → lizard-1.17.20}/test/testOutputHTML.py +0 -0
  96. {lizard-1.17.18 → lizard-1.17.20}/test/testTokenizer.py +0 -0
  97. {lizard-1.17.18 → lizard-1.17.20}/test/test_analyzer.py +0 -0
  98. {lizard-1.17.18 → lizard-1.17.20}/test/test_auto_open.py +0 -0
  99. {lizard-1.17.18 → lizard-1.17.20}/test/test_options.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lizard
3
- Version: 1.17.18
3
+ Version: 1.17.20
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/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lizard
3
- Version: 1.17.18
3
+ Version: 1.17.20
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/
@@ -3,4 +3,4 @@
3
3
  #
4
4
  # pylint: disable=missing-docstring,invalid-name
5
5
 
6
- version = "1.17.18"
6
+ version = "1.17.20"
@@ -128,7 +128,7 @@ class JavaFunctionBodyStates(JavaStates):
128
128
  self.next(self._state_global)
129
129
  self.sub_state(JavaClassBodyStates("(anonymous)", False, self.context), callback, token)
130
130
  return
131
- self.next(self._state_global)
131
+ self.next(self._state_global, token)
132
132
 
133
133
  class JavaClassBodyStates(JavaStates):
134
134
  def __init__(self, class_name, is_record, context):
@@ -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 == '*':
@@ -0,0 +1,265 @@
1
+ '''
2
+ Language parser for JSX
3
+ '''
4
+
5
+ from .javascript import JavaScriptReader
6
+ from .typescript import JSTokenizer, Tokenizer
7
+ from .code_reader import CodeReader
8
+ from .js_style_regex_expression import js_style_regex_expression
9
+ from .js_style_language_states import JavaScriptStyleLanguageStates
10
+
11
+
12
+ class TSXTokenizer(JSTokenizer):
13
+ def __init__(self):
14
+ super().__init__()
15
+
16
+ def process_token(self, token):
17
+ if token == "<":
18
+ from .jsx import XMLTagWithAttrTokenizer # Import only when needed
19
+ self.sub_tokenizer = XMLTagWithAttrTokenizer()
20
+ return
21
+
22
+ if token == "=>":
23
+ # Special handling for arrow functions
24
+ yield token
25
+ return
26
+
27
+ for tok in super().process_token(token):
28
+ yield tok
29
+
30
+
31
+ class JSXMixin:
32
+ '''Base mixin class for JSX/TSX shared functionality'''
33
+ @staticmethod
34
+ @js_style_regex_expression
35
+ def generate_tokens(source_code, addition='', token_class=None):
36
+ addition = addition +\
37
+ r"|(?:\$\w+)" + \
38
+ r"|(?:\<\/\w+\>)" + \
39
+ r"|(?:=>)" + \
40
+ r"|`.*?`"
41
+ js_tokenizer = TSXTokenizer()
42
+ for token in CodeReader.generate_tokens(
43
+ source_code, addition, token_class):
44
+ for tok in js_tokenizer(token):
45
+ yield tok
46
+
47
+ def _expecting_func_opening_bracket(self, token):
48
+ if token == '<':
49
+ self.next(self._expecting_jsx)
50
+ return
51
+ if token == '=>':
52
+ # Handle arrow functions in JSX attributes
53
+ self._handle_arrow_function()
54
+ return
55
+ super()._expecting_func_opening_bracket(token)
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
+
88
+ def _expecting_jsx(self, token):
89
+ if token == '>':
90
+ self.next(self._expecting_func_opening_bracket)
91
+
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
+
139
+ class JSXReader(JavaScriptReader, JSXMixin):
140
+ # pylint: disable=R0903
141
+
142
+ ext = ['jsx']
143
+ language_names = ['jsx']
144
+
145
+ @staticmethod
146
+ @js_style_regex_expression
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]*)*>)"
152
+ return JSXMixin.generate_tokens(source_code, addition, token_class)
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
+
159
+
160
+ class XMLTagWithAttrTokenizer(Tokenizer):
161
+ def __init__(self):
162
+ super(XMLTagWithAttrTokenizer, self).__init__()
163
+ self.tag = None
164
+ self.state = self._global_state
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
168
+
169
+ def process_token(self, token):
170
+ self.cache.append(token)
171
+ if not token.isspace():
172
+ result = self.state(token)
173
+ if result is not None:
174
+ return result
175
+ return ()
176
+
177
+ def abort(self):
178
+ self.stop()
179
+ return self.cache
180
+
181
+ def flush(self):
182
+ tmp, self.cache = self.cache, []
183
+ return [''.join(tmp)]
184
+
185
+ def _global_state(self, token):
186
+ if not isidentifier(token):
187
+ return self.abort()
188
+ self.tag = token
189
+ self.state = self._after_tag
190
+
191
+ def _after_tag(self, token):
192
+ if token == '>':
193
+ self.state = self._body
194
+ elif token == "/":
195
+ self.state = self._expecting_self_closing
196
+ elif isidentifier(token):
197
+ self.state = self._expecting_equal_sign
198
+ else:
199
+ return self.abort()
200
+
201
+ def _expecting_self_closing(self, token):
202
+ if token == ">":
203
+ self.stop()
204
+ return self.flush()
205
+ return self.abort()
206
+
207
+ def _expecting_equal_sign(self, token):
208
+ if token == '=':
209
+ self.state = self._expecting_value
210
+ else:
211
+ return self.abort()
212
+
213
+ def _expecting_value(self, token):
214
+ if token[0] in "'\"":
215
+ self.state = self._after_tag
216
+ elif token == "{":
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("}")
221
+ self.sub_tokenizer = TSXTokenizer()
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
245
+
246
+ def _body(self, token):
247
+ if token == "<":
248
+ self.sub_tokenizer = XMLTagWithAttrTokenizer()
249
+ self.cache.pop()
250
+ return self.flush()
251
+
252
+ if token.startswith("</"):
253
+ self.stop()
254
+ return self.flush()
255
+
256
+ if token == '{':
257
+ self.sub_tokenizer = TSXTokenizer()
258
+ return self.flush()
259
+
260
+
261
+ def isidentifier(token):
262
+ try:
263
+ return token.isidentifier()
264
+ except AttributeError:
265
+ return token.encode(encoding='UTF-8')[0].isalpha()
@@ -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()
@@ -1,141 +0,0 @@
1
- '''
2
- Language parser for JSX
3
- '''
4
-
5
- from .javascript import JavaScriptReader
6
- from .typescript import JSTokenizer, Tokenizer
7
- from .code_reader import CodeReader
8
- from .js_style_regex_expression import js_style_regex_expression
9
-
10
-
11
- class TSXTokenizer(JSTokenizer):
12
- def __init__(self):
13
- super().__init__()
14
-
15
- def process_token(self, token):
16
- if token == "<":
17
- from .jsx import XMLTagWithAttrTokenizer # Import only when needed
18
- self.sub_tokenizer = XMLTagWithAttrTokenizer()
19
- return
20
-
21
- for tok in super().process_token(token):
22
- yield tok
23
-
24
-
25
- class JSXMixin:
26
- '''Base mixin class for JSX/TSX shared functionality'''
27
- @staticmethod
28
- @js_style_regex_expression
29
- def generate_tokens(source_code, addition='', token_class=None):
30
- addition = addition +\
31
- r"|(?:\$\w+)" + \
32
- r"|(?:\<\/\w+\>)" + \
33
- r"|`.*?`"
34
- js_tokenizer = TSXTokenizer()
35
- for token in CodeReader.generate_tokens(
36
- source_code, addition, token_class):
37
- for tok in js_tokenizer(token):
38
- yield tok
39
-
40
- def _expecting_func_opening_bracket(self, token):
41
- if token == '<':
42
- self.next(self._expecting_jsx)
43
- return
44
- super()._expecting_func_opening_bracket(token)
45
-
46
- def _expecting_jsx(self, token):
47
- if token == '>':
48
- self.next(self._expecting_func_opening_bracket)
49
-
50
-
51
- class JSXReader(JavaScriptReader, JSXMixin):
52
- # pylint: disable=R0903
53
-
54
- ext = ['jsx']
55
- language_names = ['jsx']
56
-
57
- @staticmethod
58
- @js_style_regex_expression
59
- def generate_tokens(source_code, addition='', token_class=None):
60
- return JSXMixin.generate_tokens(source_code, addition, token_class)
61
-
62
-
63
- class XMLTagWithAttrTokenizer(Tokenizer):
64
- def __init__(self):
65
- super(XMLTagWithAttrTokenizer, self).__init__()
66
- self.tag = None
67
- self.state = self._global_state
68
- self.cache = ['<']
69
-
70
- def process_token(self, token):
71
- self.cache.append(token)
72
- if not token.isspace():
73
- result = self.state(token)
74
- if result is not None:
75
- return result
76
- return ()
77
-
78
- def abort(self):
79
- self.stop()
80
- return self.cache
81
-
82
- def flush(self):
83
- tmp, self.cache = self.cache, []
84
- return [''.join(tmp)]
85
-
86
- def _global_state(self, token):
87
- if not isidentifier(token):
88
- return self.abort()
89
- self.tag = token
90
- self.state = self._after_tag
91
-
92
- def _after_tag(self, token):
93
- if token == '>':
94
- self.state = self._body
95
- elif token == "/":
96
- self.state = self._expecting_self_closing
97
- elif isidentifier(token):
98
- self.state = self._expecting_equal_sign
99
- else:
100
- return self.abort()
101
-
102
- def _expecting_self_closing(self, token):
103
- if token == ">":
104
- self.stop()
105
- return self.flush()
106
- return self.abort()
107
-
108
- def _expecting_equal_sign(self, token):
109
- if token == '=':
110
- self.state = self._expecting_value
111
- else:
112
- return self.abort()
113
-
114
- def _expecting_value(self, token):
115
- if token[0] in "'\"":
116
- self.state = self._after_tag
117
- elif token == "{":
118
- self.cache.append("}")
119
- self.sub_tokenizer = TSXTokenizer()
120
- self.state = self._after_tag
121
-
122
- def _body(self, token):
123
- if token == "<":
124
- self.sub_tokenizer = XMLTagWithAttrTokenizer()
125
- self.cache.pop()
126
- return self.flush()
127
-
128
- if token.startswith("</"):
129
- self.stop()
130
- return self.flush()
131
-
132
- if token == '{':
133
- self.sub_tokenizer = TSXTokenizer()
134
- return self.flush()
135
-
136
-
137
- def isidentifier(token):
138
- try:
139
- return token.isidentifier()
140
- except AttributeError:
141
- return token.encode(encoding='UTF-8')[0].isalpha()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes