lizard 1.17.13__tar.gz → 1.17.15__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.
- {lizard-1.17.13 → lizard-1.17.15}/PKG-INFO +4 -4
- {lizard-1.17.13 → lizard-1.17.15}/README.rst +3 -1
- {lizard-1.17.13 → lizard-1.17.15}/lizard.egg-info/PKG-INFO +4 -4
- {lizard-1.17.13 → lizard-1.17.15}/lizard.egg-info/SOURCES.txt +4 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard.egg-info/entry_points.txt +0 -1
- {lizard-1.17.13 → lizard-1.17.15}/lizard.py +8 -11
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/csvoutput.py +11 -25
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/version.py +1 -1
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/__init__.py +8 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/clike.py +2 -2
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/code_reader.py +14 -7
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/erlang.py +10 -6
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/fortran.py +91 -47
- lizard-1.17.15/lizard_languages/javascript.py +19 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/js_style_language_states.py +20 -21
- lizard-1.17.15/lizard_languages/js_style_regex_expression.py +53 -0
- lizard-1.17.13/lizard_languages/javascript.py → lizard-1.17.15/lizard_languages/jsx.py +20 -50
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/python.py +10 -6
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/script_language.py +1 -1
- lizard-1.17.15/lizard_languages/tsx.py +24 -0
- lizard-1.17.15/lizard_languages/typescript.py +124 -0
- lizard-1.17.15/lizard_languages/vue.py +34 -0
- lizard-1.17.15/lizard_languages/zig.py +25 -0
- {lizard-1.17.13 → lizard-1.17.15}/setup.cfg +3 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testLanguages.py +4 -0
- lizard-1.17.13/lizard_languages/js_style_regex_expression.py +0 -23
- lizard-1.17.13/lizard_languages/typescript.py +0 -49
- {lizard-1.17.13 → lizard-1.17.15}/LICENSE.txt +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard.egg-info/dependency_links.txt +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard.egg-info/requires.txt +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard.egg-info/top_level.txt +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/__init__.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/auto_open.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/default_ordered_dict.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/extension_base.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/htmloutput.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/keywords.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardboolcount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardcomplextags.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardcpre.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizarddependencycount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizarddumpcomments.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardduplicate.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardduplicated_param_list.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardexitcount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardgotocount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardignoreassert.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardio.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardmccabe.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardmodified.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardnd.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardnonstrict.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardns.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardoutside.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardstatementcount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/lizardwordcount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_ext/xmloutput.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/csharp.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/gdscript.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/go.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/golike.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/java.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/kotlin.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/lua.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/objc.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/php.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/ruby.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/rubylike.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/rust.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/scala.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/solidity.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/swift.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/tnsdl.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/lizard_languages/ttcn.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/setup.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testApplication.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testAssertionExtension.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testBasicFunctionInfo.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testCOutsideComplexity.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testCPreprocessorExtension.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testCommentOptions.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testCyclomaticComplexity.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testExtension.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testFilesFilter.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testFunctionDependencyCount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testFunctionExitCount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testFunctionGotoCount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testFunctionStatementCount.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testHelpers.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testMcCabe.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testNestedStructures.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testNestingDepth.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testOutput.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testOutputCSV.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testOutputFile.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testOutputHTML.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/testTokenizer.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/test_analyzer.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/test_auto_open.py +0 -0
- {lizard-1.17.13 → lizard-1.17.15}/test/test_options.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lizard
|
|
3
|
-
Version: 1.17.
|
|
3
|
+
Version: 1.17.15
|
|
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/
|
|
@@ -52,7 +52,8 @@ A list of supported languages:
|
|
|
52
52
|
- Java
|
|
53
53
|
- C# (C Sharp)
|
|
54
54
|
- JavaScript (With ES6 and JSX)
|
|
55
|
-
- TypeScript
|
|
55
|
+
- TypeScript (With TSX)
|
|
56
|
+
- VueJS
|
|
56
57
|
- Objective-C
|
|
57
58
|
- Swift
|
|
58
59
|
- Python
|
|
@@ -68,6 +69,7 @@ A list of supported languages:
|
|
|
68
69
|
- Kotlin
|
|
69
70
|
- Solidity
|
|
70
71
|
- Erlang
|
|
72
|
+
- Zig
|
|
71
73
|
|
|
72
74
|
By default lizard will search for any source code that it knows and mix
|
|
73
75
|
all the results together. This might not be what you want. You can use
|
|
@@ -385,5 +387,3 @@ Lizard is also used as a plugin for fastlane to help check code complexity and s
|
|
|
385
387
|
- `European research project FASTEN (Fine-grained Analysis of SofTware Ecosystems as Networks, <http://fasten-project.eu/)>`_
|
|
386
388
|
- `for a quality analyzer <https://github.com/fasten-project/quality-analyzer>`_
|
|
387
389
|
|
|
388
|
-
|
|
389
|
-
|
|
@@ -21,7 +21,8 @@ A list of supported languages:
|
|
|
21
21
|
- Java
|
|
22
22
|
- C# (C Sharp)
|
|
23
23
|
- JavaScript (With ES6 and JSX)
|
|
24
|
-
- TypeScript
|
|
24
|
+
- TypeScript (With TSX)
|
|
25
|
+
- VueJS
|
|
25
26
|
- Objective-C
|
|
26
27
|
- Swift
|
|
27
28
|
- Python
|
|
@@ -37,6 +38,7 @@ A list of supported languages:
|
|
|
37
38
|
- Kotlin
|
|
38
39
|
- Solidity
|
|
39
40
|
- Erlang
|
|
41
|
+
- Zig
|
|
40
42
|
|
|
41
43
|
By default lizard will search for any source code that it knows and mix
|
|
42
44
|
all the results together. This might not be what you want. You can use
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lizard
|
|
3
|
-
Version: 1.17.
|
|
3
|
+
Version: 1.17.15
|
|
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/
|
|
@@ -52,7 +52,8 @@ A list of supported languages:
|
|
|
52
52
|
- Java
|
|
53
53
|
- C# (C Sharp)
|
|
54
54
|
- JavaScript (With ES6 and JSX)
|
|
55
|
-
- TypeScript
|
|
55
|
+
- TypeScript (With TSX)
|
|
56
|
+
- VueJS
|
|
56
57
|
- Objective-C
|
|
57
58
|
- Swift
|
|
58
59
|
- Python
|
|
@@ -68,6 +69,7 @@ A list of supported languages:
|
|
|
68
69
|
- Kotlin
|
|
69
70
|
- Solidity
|
|
70
71
|
- Erlang
|
|
72
|
+
- Zig
|
|
71
73
|
|
|
72
74
|
By default lizard will search for any source code that it knows and mix
|
|
73
75
|
all the results together. This might not be what you want. You can use
|
|
@@ -385,5 +387,3 @@ Lizard is also used as a plugin for fastlane to help check code complexity and s
|
|
|
385
387
|
- `European research project FASTEN (Fine-grained Analysis of SofTware Ecosystems as Networks, <http://fasten-project.eu/)>`_
|
|
386
388
|
- `for a quality analyzer <https://github.com/fasten-project/quality-analyzer>`_
|
|
387
389
|
|
|
388
|
-
|
|
389
|
-
|
|
@@ -50,6 +50,7 @@ lizard_languages/java.py
|
|
|
50
50
|
lizard_languages/javascript.py
|
|
51
51
|
lizard_languages/js_style_language_states.py
|
|
52
52
|
lizard_languages/js_style_regex_expression.py
|
|
53
|
+
lizard_languages/jsx.py
|
|
53
54
|
lizard_languages/kotlin.py
|
|
54
55
|
lizard_languages/lua.py
|
|
55
56
|
lizard_languages/objc.py
|
|
@@ -63,8 +64,11 @@ lizard_languages/script_language.py
|
|
|
63
64
|
lizard_languages/solidity.py
|
|
64
65
|
lizard_languages/swift.py
|
|
65
66
|
lizard_languages/tnsdl.py
|
|
67
|
+
lizard_languages/tsx.py
|
|
66
68
|
lizard_languages/ttcn.py
|
|
67
69
|
lizard_languages/typescript.py
|
|
70
|
+
lizard_languages/vue.py
|
|
71
|
+
lizard_languages/zig.py
|
|
68
72
|
test/testApplication.py
|
|
69
73
|
test/testAssertionExtension.py
|
|
70
74
|
test/testBasicFunctionInfo.py
|
|
@@ -298,8 +298,7 @@ class FunctionInfo(Nesting): # pylint: disable=R0902
|
|
|
298
298
|
return self.name.split('::')[-1]
|
|
299
299
|
|
|
300
300
|
location = property(lambda self:
|
|
301
|
-
"
|
|
302
|
-
% self.__dict__)
|
|
301
|
+
f" {self.name}@{self.start_line}-{self.end_line}@{self.filename}")
|
|
303
302
|
|
|
304
303
|
parameter_count = property(lambda self: len(self.parameters))
|
|
305
304
|
|
|
@@ -572,7 +571,9 @@ class FileAnalyzer(object): # pylint: disable=R0903
|
|
|
572
571
|
for _ in reader(tokens, reader):
|
|
573
572
|
pass
|
|
574
573
|
except RecursionError as e:
|
|
575
|
-
sys.stderr.write(
|
|
574
|
+
sys.stderr.write(
|
|
575
|
+
"[skip] fail to process '%s' with RecursionError - %s\n" %
|
|
576
|
+
(filename, e))
|
|
576
577
|
return context.fileinfo
|
|
577
578
|
|
|
578
579
|
|
|
@@ -721,17 +722,13 @@ class OutputScheme(object):
|
|
|
721
722
|
if e.get("avg_caption", None)])
|
|
722
723
|
|
|
723
724
|
def clang_warning_format(self):
|
|
724
|
-
return (
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
"{{f.{ext[value]}}} {caption}"
|
|
728
|
-
.format(ext=e, caption=e['caption'].strip())
|
|
729
|
-
for e in self.items[:-1]
|
|
730
|
-
]))
|
|
725
|
+
return ("{f.filename}:{f.start_line}: warning: {f.name} has {f.nloc} NLOC, "
|
|
726
|
+
"{f.cyclomatic_complexity} CCN, {f.token_count} token, {f.parameter_count} PARAM, "
|
|
727
|
+
"{f.length} length, {f.max_nesting_depth} ND")
|
|
731
728
|
|
|
732
729
|
def msvs_warning_format(self):
|
|
733
730
|
return (
|
|
734
|
-
"{f.filename}({f.start_line}): warning: {f.name} has " +
|
|
731
|
+
"{f.filename}({f.start_line}): warning: {f.name} ({f.long_name}) has " +
|
|
735
732
|
", ".join([
|
|
736
733
|
"{{f.{ext[value]}}} {caption}"
|
|
737
734
|
.format(ext=e, caption=e['caption'].strip())
|
|
@@ -36,9 +36,9 @@ def csv_output(result, options):
|
|
|
36
36
|
if options.verbose:
|
|
37
37
|
extension_caption = ""
|
|
38
38
|
for caption in extension_captions:
|
|
39
|
-
extension_caption = "{},{}"
|
|
40
|
-
print("NLOC,CCN,token,PARAM,length,location,file,function," +
|
|
41
|
-
"long_name,start,end{}"
|
|
39
|
+
extension_caption = f"{extension_caption},{caption}"
|
|
40
|
+
print(f"NLOC,CCN,token,PARAM,length,location,file,function," +
|
|
41
|
+
f"long_name,start,end{extension_caption}")
|
|
42
42
|
|
|
43
43
|
for source_file in result:
|
|
44
44
|
if source_file:
|
|
@@ -46,25 +46,11 @@ def csv_output(result, options):
|
|
|
46
46
|
if source_function:
|
|
47
47
|
extension_string = ''
|
|
48
48
|
for variable in extension_variables:
|
|
49
|
-
extension_string =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
source_function.length,
|
|
58
|
-
"{}@{}-{}@{}".format(
|
|
59
|
-
source_function.name.replace("\"", "'"),
|
|
60
|
-
source_function.start_line,
|
|
61
|
-
source_function.end_line,
|
|
62
|
-
source_file.filename
|
|
63
|
-
),
|
|
64
|
-
source_file.filename,
|
|
65
|
-
source_function.name.replace("\"", "'"),
|
|
66
|
-
source_function.long_name.replace("\"", "'"),
|
|
67
|
-
source_function.start_line,
|
|
68
|
-
source_function.end_line,
|
|
69
|
-
extension_string
|
|
70
|
-
))
|
|
49
|
+
extension_string = f"{extension_string},{source_function.__getattribute__(variable)}"
|
|
50
|
+
print(f"{source_function.nloc},{source_function.cyclomatic_complexity},"
|
|
51
|
+
f"{source_function.token_count},{len(source_function.parameters)},"
|
|
52
|
+
f'{source_function.length},"{source_function.name.replace(chr(34), chr(39))}@'
|
|
53
|
+
f'{source_function.start_line}-{source_function.end_line}@{source_file.filename}",'
|
|
54
|
+
f'"{source_file.filename}","{source_function.name.replace(chr(34), chr(39))}",'
|
|
55
|
+
f'"{source_function.long_name.replace(chr(34), chr(39))}",'
|
|
56
|
+
f"{source_function.start_line},{source_function.end_line}{extension_string}")
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
''' programming languages of lizard '''
|
|
2
2
|
|
|
3
|
+
from lizard_languages.zig import ZigReader
|
|
3
4
|
from .clike import CLikeReader
|
|
4
5
|
from .erlang import ErlangReader
|
|
5
6
|
from .java import JavaReader
|
|
@@ -20,6 +21,9 @@ from .rust import RustReader
|
|
|
20
21
|
from .typescript import TypeScriptReader
|
|
21
22
|
from .fortran import FortranReader
|
|
22
23
|
from .solidity import SolidityReader
|
|
24
|
+
from .jsx import JSXReader
|
|
25
|
+
from .tsx import TSXReader
|
|
26
|
+
from .vue import VueReader
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
def languages():
|
|
@@ -44,6 +48,10 @@ def languages():
|
|
|
44
48
|
KotlinReader,
|
|
45
49
|
SolidityReader,
|
|
46
50
|
ErlangReader,
|
|
51
|
+
ZigReader,
|
|
52
|
+
JSXReader,
|
|
53
|
+
TSXReader,
|
|
54
|
+
VueReader,
|
|
47
55
|
]
|
|
48
56
|
|
|
49
57
|
|
|
@@ -182,7 +182,7 @@ class CLikeStates(CodeStateMachine):
|
|
|
182
182
|
self.context.add_to_function_name(' ' + token)
|
|
183
183
|
|
|
184
184
|
def _state_name_with_space(self, token):
|
|
185
|
-
self._state = self._state_operator\
|
|
185
|
+
self._state = self._state_operator \
|
|
186
186
|
if token == 'operator' else self._state_function
|
|
187
187
|
self.context.add_to_function_name(token)
|
|
188
188
|
|
|
@@ -196,7 +196,7 @@ class CLikeStates(CodeStateMachine):
|
|
|
196
196
|
else:
|
|
197
197
|
self.next(self._state_global)
|
|
198
198
|
elif len(self.bracket_stack) == 1:
|
|
199
|
-
if token != 'void':
|
|
199
|
+
if token != 'void': # void is a reserved keyword, meaning no parameters
|
|
200
200
|
self.context.parameter(token)
|
|
201
201
|
return
|
|
202
202
|
self.context.add_to_long_function_name(token)
|
|
@@ -8,7 +8,7 @@ from functools import reduce
|
|
|
8
8
|
from operator import or_
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class CodeStateMachine
|
|
11
|
+
class CodeStateMachine:
|
|
12
12
|
""" the state machine """
|
|
13
13
|
# pylint: disable=R0903
|
|
14
14
|
# pylint: disable=R0902
|
|
@@ -50,6 +50,7 @@ class CodeStateMachine(object):
|
|
|
50
50
|
self.next(self.saved_state)
|
|
51
51
|
if self.callback:
|
|
52
52
|
self.callback()
|
|
53
|
+
self.callback = None
|
|
53
54
|
self.last_token = token
|
|
54
55
|
if self.to_exit:
|
|
55
56
|
return True
|
|
@@ -117,11 +118,13 @@ class CodeReader:
|
|
|
117
118
|
def _generate_tokens(source, add, flags=0):
|
|
118
119
|
# DO NOT put any sub groups in the regex. Good for performance
|
|
119
120
|
_until_end = r"(?:\\\n|[^\n])*"
|
|
120
|
-
combined_symbols = [
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
combined_symbols = [
|
|
122
|
+
"<<=", ">>=", "||", "&&", "===", "!==",
|
|
123
|
+
"==", "!=", "<=", ">=", "->", "=>",
|
|
124
|
+
"++", "--", '+=', '-=',
|
|
125
|
+
"+", "-", '*', '/',
|
|
126
|
+
'*=', '/=', '^=', '&=', '|=', "..."
|
|
127
|
+
]
|
|
125
128
|
token_pattern = re.compile(
|
|
126
129
|
r"(?:" +
|
|
127
130
|
r"\/\*.*?\*\/" +
|
|
@@ -171,8 +174,12 @@ class CodeReader:
|
|
|
171
174
|
pattern = re.compile(r'\(\?[aiLmsux]+\)')
|
|
172
175
|
re_flags = ''.join(opt[2:-1] for opt in pattern.findall(addition))
|
|
173
176
|
flags = reduce(or_, (flag_dict[flag] for flag in re_flags), 0)
|
|
177
|
+
cleaned_addition = pattern.sub('', addition)
|
|
174
178
|
|
|
175
|
-
return _generate_tokens(
|
|
179
|
+
return _generate_tokens(
|
|
180
|
+
source_code,
|
|
181
|
+
cleaned_addition,
|
|
182
|
+
flags=flags)
|
|
176
183
|
|
|
177
184
|
def __call__(self, tokens, reader):
|
|
178
185
|
self.context = reader.context
|
|
@@ -26,8 +26,12 @@ class ErlangReader(CodeReader):
|
|
|
26
26
|
|
|
27
27
|
@staticmethod
|
|
28
28
|
def generate_tokens(source_code, addition='', token_class=None):
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
lexer = lexers.get_lexer_by_name('erlang')
|
|
30
|
+
tokens = lex(source_code, lexer=lexer)
|
|
31
|
+
return map(
|
|
32
|
+
lambda x: x[1],
|
|
33
|
+
filter(lambda x: x[0] != py_token.Whitespace, tokens)
|
|
34
|
+
)
|
|
31
35
|
|
|
32
36
|
|
|
33
37
|
class ErlangStates(CodeStateMachine):
|
|
@@ -77,8 +81,8 @@ class ErlangStates(CodeStateMachine):
|
|
|
77
81
|
if token == '-':
|
|
78
82
|
self.punctuated = True
|
|
79
83
|
elif token == '>' and self.punctuated:
|
|
80
|
-
if len(self.context.stacked_functions) <= 1 or
|
|
81
|
-
self.context.current_function.name == 'fun':
|
|
84
|
+
if (len(self.context.stacked_functions) <= 1 or
|
|
85
|
+
self.context.current_function.name == 'fun'):
|
|
82
86
|
self.next(self._state_func_first_line, token)
|
|
83
87
|
else:
|
|
84
88
|
self.func_match_failed(token)
|
|
@@ -93,8 +97,8 @@ class ErlangStates(CodeStateMachine):
|
|
|
93
97
|
|
|
94
98
|
def _state_nested_end(self, token):
|
|
95
99
|
if token == '.' or token == ',':
|
|
96
|
-
if len(self.context.stacked_functions) > 1
|
|
97
|
-
|
|
100
|
+
if (len(self.context.stacked_functions) > 1 and
|
|
101
|
+
self.context.stacked_functions[-1].name == 'fun'):
|
|
98
102
|
self.statemachine_return()
|
|
99
103
|
return
|
|
100
104
|
|
|
@@ -6,57 +6,65 @@ import re
|
|
|
6
6
|
from .code_reader import CodeStateMachine, CodeReader
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
class FortranCommentsMixin(object):
|
|
9
|
+
class FortranCommentsMixin:
|
|
11
10
|
@staticmethod
|
|
12
11
|
def get_comment_from_token(token):
|
|
13
12
|
if token.startswith('!'):
|
|
14
13
|
return token[1:]
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
# pylint: disable=R0903
|
|
18
16
|
class FortranReader(CodeReader, FortranCommentsMixin):
|
|
19
|
-
'''
|
|
17
|
+
'''This is the reader for Fortran.'''
|
|
20
18
|
|
|
21
19
|
ext = ['f70', 'f90', 'f95', 'f03', 'f08', 'f', 'for', 'ftn', 'fpp']
|
|
22
20
|
language_names = ['fortran']
|
|
23
|
-
|
|
21
|
+
|
|
22
|
+
# Conditions need to have all the cases because the matching is case-insensitive
|
|
23
|
+
# and is not done here.
|
|
24
|
+
_conditions = {
|
|
24
25
|
'IF', 'DO', '.AND.', '.OR.', 'CASE',
|
|
25
|
-
'if', 'do', '.and.', '.or.', 'case'
|
|
26
|
-
|
|
26
|
+
'if', 'do', '.and.', '.or.', 'case'
|
|
27
|
+
}
|
|
28
|
+
_blocks = [
|
|
29
|
+
'PROGRAM', 'MODULE', 'SUBMODULE', 'SUBROUTINE', 'FUNCTION', 'TYPE',
|
|
30
|
+
'INTERFACE', 'BLOCK', 'IF', 'DO', 'FORALL', 'WHERE', 'SELECT', 'ASSOCIATE'
|
|
31
|
+
]
|
|
27
32
|
|
|
28
33
|
def __init__(self, context):
|
|
29
|
-
super(
|
|
34
|
+
super().__init__(context)
|
|
30
35
|
self.macro_disabled = False
|
|
31
36
|
self.parallel_states = [FortranStates(context, self)]
|
|
32
37
|
|
|
33
38
|
@staticmethod
|
|
34
39
|
def generate_tokens(source_code, addition='', token_class=None):
|
|
35
40
|
_until_end = r'(?:\\\n|[^\n])*'
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
block_endings = '|'.join(r'END\s*{0}'.format(_) for _ in FortranReader._blocks)
|
|
42
|
+
# Include all patterns and the (?i) flag in addition
|
|
43
|
+
addition = (
|
|
38
44
|
r'(?i)'
|
|
39
|
-
r'
|
|
40
|
-
r'
|
|
41
|
-
r'
|
|
42
|
-
r'
|
|
43
|
-
r'
|
|
44
|
-
r'
|
|
45
|
-
r'
|
|
46
|
-
|
|
47
|
-
addition
|
|
48
|
-
|
|
45
|
+
r'\/\/|'
|
|
46
|
+
r'\#' + _until_end + r'|'
|
|
47
|
+
r'\!' + _until_end + r'|'
|
|
48
|
+
r'^\*' + _until_end + r'|'
|
|
49
|
+
r'\.OR\.|'
|
|
50
|
+
r'\.AND\.|'
|
|
51
|
+
r'ELSE\s+IF|'
|
|
52
|
+
r'MODULE\s+PROCEDURE|'
|
|
53
|
+
+ block_endings + addition
|
|
54
|
+
)
|
|
55
|
+
return CodeReader.generate_tokens(
|
|
56
|
+
source_code, addition=addition, token_class=token_class)
|
|
49
57
|
|
|
50
58
|
def preprocess(self, tokens):
|
|
51
59
|
macro_depth = 0
|
|
52
60
|
new_line = True
|
|
53
61
|
for token in tokens:
|
|
54
|
-
if new_line and token[0].upper() in ('
|
|
55
|
-
token = '!'+token[1:]
|
|
62
|
+
if new_line and token[0].upper() in ('C', '*'):
|
|
63
|
+
token = '!' + token[1:]
|
|
56
64
|
new_line = token == '\n'
|
|
57
|
-
|
|
58
|
-
if
|
|
59
|
-
macro =
|
|
65
|
+
macro_match = re.match(r'#\s*(\w+)', token)
|
|
66
|
+
if macro_match:
|
|
67
|
+
macro = macro_match.group(1).lower()
|
|
60
68
|
if macro in ('if', 'ifdef', 'ifndef', 'elif'):
|
|
61
69
|
self.context.add_condition()
|
|
62
70
|
if macro_depth > 0:
|
|
@@ -66,22 +74,29 @@ class FortranReader(CodeReader, FortranCommentsMixin):
|
|
|
66
74
|
macro_depth -= 1
|
|
67
75
|
elif macro in ('else', 'elif'):
|
|
68
76
|
macro_depth += 1
|
|
69
|
-
#
|
|
70
|
-
# only the first branch of #if #elif #else
|
|
71
|
-
# is read by the FortranStateMachine
|
|
77
|
+
# Only the first branch of #if #elif #else is read
|
|
72
78
|
self.macro_disabled = macro_depth != 0
|
|
73
79
|
elif not token.isspace() or token == '\n':
|
|
74
80
|
yield token
|
|
75
81
|
|
|
76
|
-
|
|
82
|
+
|
|
77
83
|
class FortranStates(CodeStateMachine):
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
_ends = re.compile(
|
|
85
|
+
'|'.join(r'END\s*{0}'.format(_) for _ in FortranReader._blocks), re.I)
|
|
86
|
+
|
|
87
|
+
# Define token groups to eliminate duplication
|
|
88
|
+
IGNORE_NEXT_TOKENS = {'%', '::', 'SAVE', 'DATA'}
|
|
89
|
+
IGNORE_VAR_TOKENS = {'INTEGER', 'REAL', 'COMPLEX', 'LOGICAL', 'CHARACTER'}
|
|
90
|
+
RESET_STATE_TOKENS = {'RECURSIVE', 'ELEMENTAL'}
|
|
91
|
+
FUNCTION_NAME_TOKENS = {'SUBROUTINE', 'FUNCTION'}
|
|
92
|
+
NESTING_KEYWORDS = {'FORALL', 'WHERE', 'SELECT', 'INTERFACE', 'ASSOCIATE'}
|
|
93
|
+
PROCEDURE_TOKENS = {'PROCEDURE', 'MODULE PROCEDURE'}
|
|
81
94
|
|
|
82
95
|
def __init__(self, context, reader):
|
|
83
|
-
super(
|
|
96
|
+
super().__init__(context)
|
|
84
97
|
self.reader = reader
|
|
98
|
+
self.last_token = None
|
|
99
|
+
self.in_interface = False
|
|
85
100
|
|
|
86
101
|
def __call__(self, token, reader=None):
|
|
87
102
|
if self.reader.macro_disabled:
|
|
@@ -96,28 +111,35 @@ class FortranStates(CodeStateMachine):
|
|
|
96
111
|
|
|
97
112
|
def _state_global(self, token):
|
|
98
113
|
token_upper = token.upper()
|
|
99
|
-
if token_upper in
|
|
114
|
+
if token_upper in self.IGNORE_NEXT_TOKENS:
|
|
100
115
|
self._state = self._ignore_next
|
|
101
|
-
elif token_upper in
|
|
116
|
+
elif token_upper in self.IGNORE_VAR_TOKENS:
|
|
102
117
|
self._state = self._ignore_var
|
|
103
118
|
elif token == '(':
|
|
104
119
|
self.next(self._ignore_expr, token)
|
|
105
|
-
elif token_upper in
|
|
120
|
+
elif token_upper in self.RESET_STATE_TOKENS:
|
|
121
|
+
self.reset_state()
|
|
122
|
+
elif token_upper in self.FUNCTION_NAME_TOKENS:
|
|
123
|
+
self._state = self._function_name
|
|
124
|
+
elif token_upper == 'PROGRAM':
|
|
106
125
|
self._state = self._namespace
|
|
107
126
|
elif token_upper == 'MODULE':
|
|
127
|
+
self._state = self._module_or_procedure
|
|
128
|
+
elif token_upper == 'SUBMODULE':
|
|
108
129
|
self._state = self._module
|
|
109
|
-
|
|
110
|
-
self._state = self._function_name
|
|
130
|
+
self._module(token)
|
|
111
131
|
elif token_upper == 'TYPE':
|
|
112
132
|
self._state = self._type
|
|
113
133
|
elif token_upper == 'IF':
|
|
114
134
|
self._state = self._if
|
|
115
|
-
elif token_upper
|
|
135
|
+
elif token_upper == 'BLOCK':
|
|
116
136
|
self._state = self._ignore_if_paren
|
|
117
|
-
elif token_upper
|
|
137
|
+
elif token_upper == 'DO':
|
|
118
138
|
self._state = self._ignore_if_label
|
|
119
|
-
elif token_upper in
|
|
139
|
+
elif token_upper in self.NESTING_KEYWORDS:
|
|
120
140
|
self.context.add_bare_nesting()
|
|
141
|
+
if token_upper == 'INTERFACE':
|
|
142
|
+
self.in_interface = True
|
|
121
143
|
elif token_upper == 'ELSE':
|
|
122
144
|
self.context.pop_nesting()
|
|
123
145
|
self.context.add_bare_nesting()
|
|
@@ -127,6 +149,9 @@ class FortranStates(CodeStateMachine):
|
|
|
127
149
|
self.context.add_condition()
|
|
128
150
|
self._state = self._if
|
|
129
151
|
elif token_upper == 'END' or self._ends.match(token):
|
|
152
|
+
end_token_upper = token_upper.replace(' ', '')
|
|
153
|
+
if end_token_upper.startswith('ENDINTERFACE'):
|
|
154
|
+
self.in_interface = False
|
|
130
155
|
self.context.pop_nesting()
|
|
131
156
|
|
|
132
157
|
def reset_state(self, token=None):
|
|
@@ -134,12 +159,11 @@ class FortranStates(CodeStateMachine):
|
|
|
134
159
|
if token is not None:
|
|
135
160
|
self._state_global(token)
|
|
136
161
|
|
|
137
|
-
# pylint: disable=unused-argument
|
|
138
162
|
def _ignore_next(self, token):
|
|
139
163
|
self.reset_state()
|
|
140
164
|
|
|
141
165
|
def _ignore_var(self, token):
|
|
142
|
-
if token.upper() in
|
|
166
|
+
if token.upper() in self.FUNCTION_NAME_TOKENS:
|
|
143
167
|
self.reset_state(token)
|
|
144
168
|
else:
|
|
145
169
|
self.reset_state()
|
|
@@ -152,7 +176,7 @@ class FortranStates(CodeStateMachine):
|
|
|
152
176
|
self.reset_state()
|
|
153
177
|
|
|
154
178
|
def _ignore_if_label(self, token):
|
|
155
|
-
if
|
|
179
|
+
if token.isdigit():
|
|
156
180
|
self.reset_state()
|
|
157
181
|
else:
|
|
158
182
|
self.context.add_bare_nesting()
|
|
@@ -184,11 +208,24 @@ class FortranStates(CodeStateMachine):
|
|
|
184
208
|
self.reset_state(token)
|
|
185
209
|
|
|
186
210
|
def _module(self, token):
|
|
187
|
-
if token.upper()
|
|
188
|
-
self.
|
|
211
|
+
if token.upper() in self.FUNCTION_NAME_TOKENS:
|
|
212
|
+
self._state = self._function_name
|
|
213
|
+
elif token.upper() in self.PROCEDURE_TOKENS:
|
|
214
|
+
self._state = self._procedure
|
|
189
215
|
else:
|
|
190
216
|
self._namespace(token)
|
|
191
217
|
|
|
218
|
+
def _procedure(self, token):
|
|
219
|
+
# Start a new function regardless of context
|
|
220
|
+
if self.last_token and self.last_token.upper() == 'MODULE':
|
|
221
|
+
# For "module procedure" case, use the current token as function name
|
|
222
|
+
self.context.restart_new_function(token)
|
|
223
|
+
else:
|
|
224
|
+
# For standalone "procedure" case
|
|
225
|
+
self.context.restart_new_function(token)
|
|
226
|
+
self.context.add_bare_nesting()
|
|
227
|
+
self.reset_state()
|
|
228
|
+
|
|
192
229
|
def _type(self, token):
|
|
193
230
|
if token in (',', '::') or token[0].isalpha():
|
|
194
231
|
self._namespace(token)
|
|
@@ -210,8 +247,15 @@ class FortranStates(CodeStateMachine):
|
|
|
210
247
|
pass
|
|
211
248
|
|
|
212
249
|
def _if_then(self, token):
|
|
213
|
-
|
|
250
|
+
token_upper = token.upper()
|
|
251
|
+
if token_upper == 'THEN':
|
|
214
252
|
self.context.add_bare_nesting()
|
|
215
253
|
self.reset_state()
|
|
216
254
|
else:
|
|
217
255
|
self.reset_state(token)
|
|
256
|
+
|
|
257
|
+
def _module_or_procedure(self, token):
|
|
258
|
+
if token.upper() == 'PROCEDURE':
|
|
259
|
+
self._state = self._procedure
|
|
260
|
+
else:
|
|
261
|
+
self._module(token)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Language parser for JavaScript
|
|
3
|
+
'''
|
|
4
|
+
|
|
5
|
+
from .code_reader import CodeReader
|
|
6
|
+
from .clike import CCppCommentsMixin
|
|
7
|
+
from .js_style_regex_expression import js_style_regex_expression
|
|
8
|
+
from .js_style_language_states import JavaScriptStyleLanguageStates
|
|
9
|
+
from .typescript import TypeScriptReader, JSTokenizer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class JavaScriptReader(TypeScriptReader):
|
|
13
|
+
# pylint: disable=R0903
|
|
14
|
+
|
|
15
|
+
ext = ['js']
|
|
16
|
+
language_names = ['javascript', 'js']
|
|
17
|
+
|
|
18
|
+
def __init__(self, context):
|
|
19
|
+
super(JavaScriptReader, self).__init__(context)
|