lizard 1.18.0__tar.gz → 1.19.0__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 (102) hide show
  1. {lizard-1.18.0 → lizard-1.19.0}/PKG-INFO +29 -19
  2. {lizard-1.18.0 → lizard-1.19.0}/README.rst +28 -18
  3. {lizard-1.18.0 → lizard-1.19.0}/lizard.egg-info/PKG-INFO +29 -19
  4. {lizard-1.18.0 → lizard-1.19.0}/lizard.egg-info/SOURCES.txt +1 -0
  5. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/htmloutput.py +86 -17
  6. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardnd.py +64 -1
  7. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/version.py +1 -1
  8. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/__init__.py +2 -0
  9. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/clike.py +1 -1
  10. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/code_reader.py +1 -1
  11. lizard-1.19.0/lizard_languages/plsql.py +419 -0
  12. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/typescript.py +52 -2
  13. {lizard-1.18.0 → lizard-1.19.0}/test/testNestingDepth.py +48 -0
  14. lizard-1.19.0/test/testOutputHTML.py +42 -0
  15. lizard-1.18.0/test/testOutputHTML.py +0 -21
  16. {lizard-1.18.0 → lizard-1.19.0}/LICENSE.txt +0 -0
  17. {lizard-1.18.0 → lizard-1.19.0}/lizard.egg-info/dependency_links.txt +0 -0
  18. {lizard-1.18.0 → lizard-1.19.0}/lizard.egg-info/entry_points.txt +0 -0
  19. {lizard-1.18.0 → lizard-1.19.0}/lizard.egg-info/requires.txt +0 -0
  20. {lizard-1.18.0 → lizard-1.19.0}/lizard.egg-info/top_level.txt +0 -0
  21. {lizard-1.18.0 → lizard-1.19.0}/lizard.py +0 -0
  22. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/__init__.py +0 -0
  23. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/auto_open.py +0 -0
  24. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/checkstyleoutput.py +0 -0
  25. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/csvoutput.py +0 -0
  26. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/default_ordered_dict.py +0 -0
  27. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/extension_base.py +0 -0
  28. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/keywords.py +0 -0
  29. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardboolcount.py +0 -0
  30. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardcomplextags.py +0 -0
  31. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardcpre.py +0 -0
  32. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizarddependencycount.py +0 -0
  33. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizarddumpcomments.py +0 -0
  34. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardduplicate.py +0 -0
  35. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardduplicated_param_list.py +0 -0
  36. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardexitcount.py +0 -0
  37. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardgotocount.py +0 -0
  38. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardignoreassert.py +0 -0
  39. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardio.py +0 -0
  40. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardmccabe.py +0 -0
  41. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardmodified.py +0 -0
  42. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardnonstrict.py +0 -0
  43. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardns.py +0 -0
  44. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardoutside.py +0 -0
  45. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardstatementcount.py +0 -0
  46. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/lizardwordcount.py +0 -0
  47. {lizard-1.18.0 → lizard-1.19.0}/lizard_ext/xmloutput.py +0 -0
  48. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/csharp.py +0 -0
  49. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/erlang.py +0 -0
  50. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/fortran.py +0 -0
  51. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/gdscript.py +0 -0
  52. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/go.py +0 -0
  53. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/golike.py +0 -0
  54. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/java.py +0 -0
  55. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/javascript.py +0 -0
  56. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/js_style_regex_expression.py +0 -0
  57. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/kotlin.py +0 -0
  58. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/lua.py +0 -0
  59. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/objc.py +0 -0
  60. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/perl.py +0 -0
  61. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/php.py +0 -0
  62. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/python.py +0 -0
  63. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/r.py +0 -0
  64. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/ruby.py +0 -0
  65. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/rubylike.py +0 -0
  66. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/rust.py +0 -0
  67. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/scala.py +0 -0
  68. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/script_language.py +0 -0
  69. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/solidity.py +0 -0
  70. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/st.py +0 -0
  71. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/swift.py +0 -0
  72. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/tnsdl.py +0 -0
  73. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/tsx.py +0 -0
  74. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/ttcn.py +0 -0
  75. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/vue.py +0 -0
  76. {lizard-1.18.0 → lizard-1.19.0}/lizard_languages/zig.py +0 -0
  77. {lizard-1.18.0 → lizard-1.19.0}/setup.cfg +0 -0
  78. {lizard-1.18.0 → lizard-1.19.0}/setup.py +0 -0
  79. {lizard-1.18.0 → lizard-1.19.0}/test/testApplication.py +0 -0
  80. {lizard-1.18.0 → lizard-1.19.0}/test/testAssertionExtension.py +0 -0
  81. {lizard-1.18.0 → lizard-1.19.0}/test/testBasicFunctionInfo.py +0 -0
  82. {lizard-1.18.0 → lizard-1.19.0}/test/testCOutsideComplexity.py +0 -0
  83. {lizard-1.18.0 → lizard-1.19.0}/test/testCPreprocessorExtension.py +0 -0
  84. {lizard-1.18.0 → lizard-1.19.0}/test/testCommentOptions.py +0 -0
  85. {lizard-1.18.0 → lizard-1.19.0}/test/testCyclomaticComplexity.py +0 -0
  86. {lizard-1.18.0 → lizard-1.19.0}/test/testExtension.py +0 -0
  87. {lizard-1.18.0 → lizard-1.19.0}/test/testFilesFilter.py +0 -0
  88. {lizard-1.18.0 → lizard-1.19.0}/test/testFunctionDependencyCount.py +0 -0
  89. {lizard-1.18.0 → lizard-1.19.0}/test/testFunctionExitCount.py +0 -0
  90. {lizard-1.18.0 → lizard-1.19.0}/test/testFunctionGotoCount.py +0 -0
  91. {lizard-1.18.0 → lizard-1.19.0}/test/testFunctionStatementCount.py +0 -0
  92. {lizard-1.18.0 → lizard-1.19.0}/test/testHelpers.py +0 -0
  93. {lizard-1.18.0 → lizard-1.19.0}/test/testLanguages.py +0 -0
  94. {lizard-1.18.0 → lizard-1.19.0}/test/testMcCabe.py +0 -0
  95. {lizard-1.18.0 → lizard-1.19.0}/test/testNestedStructures.py +0 -0
  96. {lizard-1.18.0 → lizard-1.19.0}/test/testOutput.py +0 -0
  97. {lizard-1.18.0 → lizard-1.19.0}/test/testOutputCSV.py +0 -0
  98. {lizard-1.18.0 → lizard-1.19.0}/test/testOutputFile.py +0 -0
  99. {lizard-1.18.0 → lizard-1.19.0}/test/testTokenizer.py +0 -0
  100. {lizard-1.18.0 → lizard-1.19.0}/test/test_analyzer.py +0 -0
  101. {lizard-1.18.0 → lizard-1.19.0}/test/test_auto_open.py +0 -0
  102. {lizard-1.18.0 → lizard-1.19.0}/test/test_options.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lizard
3
- Version: 1.18.0
3
+ Version: 1.19.0
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/
@@ -48,31 +48,32 @@ code analysis.
48
48
 
49
49
  A list of supported languages:
50
50
 
51
+ - C# (C Sharp)
51
52
  - C/C++ (works with C++14)
53
+ - Erlang
54
+ - Fortran
55
+ - GDScript
56
+ - Golang
52
57
  - Java
53
- - C# (C Sharp)
54
58
  - JavaScript (With ES6 and JSX)
55
- - TypeScript (With TSX)
56
- - VueJS
59
+ - Kotlin
60
+ - Lua
57
61
  - Objective-C
58
- - Swift
62
+ - Perl
63
+ - PHP
64
+ - PL/SQL
59
65
  - Python
66
+ - R
60
67
  - Ruby
61
- - TTCN-3
62
- - PHP
63
- - Scala
64
- - GDScript
65
- - Golang
66
- - Lua
67
68
  - Rust
68
- - Fortran
69
- - Kotlin
69
+ - Scala
70
70
  - Solidity
71
- - Erlang
72
- - Zig
73
- - Perl
74
71
  - Structured Text (St)
75
- - R
72
+ - Swift
73
+ - TTCN-3
74
+ - TypeScript (With TSX)
75
+ - VueJS
76
+ - Zig
76
77
 
77
78
  By default lizard will search for any source code that it knows and mix
78
79
  all the results together. This might not be what you want. You can use
@@ -160,7 +161,7 @@ Options
160
161
  search for all languages it knows. `lizard -l cpp -l java`searches for
161
162
  C++ and Java code. The available languages are: cpp, java, csharp,
162
163
  javascript, python, objectivec, ttcn, ruby, php, swift, scala, GDScript,
163
- go, lua, rust, typescript
164
+ go, lua, rust, typescript, plsql
164
165
  -V, --verbose Output in verbose mode (long function name)
165
166
  -C CCN, --CCN CCN Threshold for cyclomatic complexity number warning. The default value is
166
167
  15. Functions with CCN bigger than it will generate warning
@@ -195,7 +196,7 @@ Options
195
196
  -X, --xml Generate XML in cppncss style instead of the tabular output. Useful to
196
197
  generate report in Jenkins server
197
198
  --csv Generate CSV output as a transform of the default output
198
- -H, --html Output HTML report
199
+ -H, --html Output HTML report with interactive DataTables (sortable, searchable, filterable)
199
200
  --checkstyle Generate Checkstyle XML output for integration with Jenkins and other tools
200
201
  -m, --modified Calculate modified cyclomatic complexity number , which count a
201
202
  switch/case with multiple cases as one CCN.
@@ -413,5 +414,14 @@ Lizard is also used as a plugin for fastlane to help check code complexity and s
413
414
  - `European research project FASTEN (Fine-grained Analysis of SofTware Ecosystems as Networks, <http://fasten-project.eu/)>`_
414
415
  - `for a quality analyzer <https://github.com/fasten-project/quality-analyzer>`_
415
416
 
417
+ How To Contribute
418
+ -----------------
419
+
420
+ Contributions are welcome. Please refer to the rules and development workflow in:
421
+
422
+ - https://github.com/terryyin/lizard/tree/master/.cursor/rules
423
+
424
+ These guidelines are usable by both AI assistants and human contributors — what works for AI works for "I" as well — to keep changes cohesive, simple, and well-tested.
425
+
416
426
 
417
427
 
@@ -17,31 +17,32 @@ code analysis.
17
17
 
18
18
  A list of supported languages:
19
19
 
20
+ - C# (C Sharp)
20
21
  - C/C++ (works with C++14)
22
+ - Erlang
23
+ - Fortran
24
+ - GDScript
25
+ - Golang
21
26
  - Java
22
- - C# (C Sharp)
23
27
  - JavaScript (With ES6 and JSX)
24
- - TypeScript (With TSX)
25
- - VueJS
28
+ - Kotlin
29
+ - Lua
26
30
  - Objective-C
27
- - Swift
31
+ - Perl
32
+ - PHP
33
+ - PL/SQL
28
34
  - Python
35
+ - R
29
36
  - Ruby
30
- - TTCN-3
31
- - PHP
32
- - Scala
33
- - GDScript
34
- - Golang
35
- - Lua
36
37
  - Rust
37
- - Fortran
38
- - Kotlin
38
+ - Scala
39
39
  - Solidity
40
- - Erlang
41
- - Zig
42
- - Perl
43
40
  - Structured Text (St)
44
- - R
41
+ - Swift
42
+ - TTCN-3
43
+ - TypeScript (With TSX)
44
+ - VueJS
45
+ - Zig
45
46
 
46
47
  By default lizard will search for any source code that it knows and mix
47
48
  all the results together. This might not be what you want. You can use
@@ -129,7 +130,7 @@ Options
129
130
  search for all languages it knows. `lizard -l cpp -l java`searches for
130
131
  C++ and Java code. The available languages are: cpp, java, csharp,
131
132
  javascript, python, objectivec, ttcn, ruby, php, swift, scala, GDScript,
132
- go, lua, rust, typescript
133
+ go, lua, rust, typescript, plsql
133
134
  -V, --verbose Output in verbose mode (long function name)
134
135
  -C CCN, --CCN CCN Threshold for cyclomatic complexity number warning. The default value is
135
136
  15. Functions with CCN bigger than it will generate warning
@@ -164,7 +165,7 @@ Options
164
165
  -X, --xml Generate XML in cppncss style instead of the tabular output. Useful to
165
166
  generate report in Jenkins server
166
167
  --csv Generate CSV output as a transform of the default output
167
- -H, --html Output HTML report
168
+ -H, --html Output HTML report with interactive DataTables (sortable, searchable, filterable)
168
169
  --checkstyle Generate Checkstyle XML output for integration with Jenkins and other tools
169
170
  -m, --modified Calculate modified cyclomatic complexity number , which count a
170
171
  switch/case with multiple cases as one CCN.
@@ -382,3 +383,12 @@ Lizard is also used as a plugin for fastlane to help check code complexity and s
382
383
  - `European research project FASTEN (Fine-grained Analysis of SofTware Ecosystems as Networks, <http://fasten-project.eu/)>`_
383
384
  - `for a quality analyzer <https://github.com/fasten-project/quality-analyzer>`_
384
385
 
386
+ How To Contribute
387
+ -----------------
388
+
389
+ Contributions are welcome. Please refer to the rules and development workflow in:
390
+
391
+ - https://github.com/terryyin/lizard/tree/master/.cursor/rules
392
+
393
+ These guidelines are usable by both AI assistants and human contributors — what works for AI works for "I" as well — to keep changes cohesive, simple, and well-tested.
394
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lizard
3
- Version: 1.18.0
3
+ Version: 1.19.0
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/
@@ -48,31 +48,32 @@ code analysis.
48
48
 
49
49
  A list of supported languages:
50
50
 
51
+ - C# (C Sharp)
51
52
  - C/C++ (works with C++14)
53
+ - Erlang
54
+ - Fortran
55
+ - GDScript
56
+ - Golang
52
57
  - Java
53
- - C# (C Sharp)
54
58
  - JavaScript (With ES6 and JSX)
55
- - TypeScript (With TSX)
56
- - VueJS
59
+ - Kotlin
60
+ - Lua
57
61
  - Objective-C
58
- - Swift
62
+ - Perl
63
+ - PHP
64
+ - PL/SQL
59
65
  - Python
66
+ - R
60
67
  - Ruby
61
- - TTCN-3
62
- - PHP
63
- - Scala
64
- - GDScript
65
- - Golang
66
- - Lua
67
68
  - Rust
68
- - Fortran
69
- - Kotlin
69
+ - Scala
70
70
  - Solidity
71
- - Erlang
72
- - Zig
73
- - Perl
74
71
  - Structured Text (St)
75
- - R
72
+ - Swift
73
+ - TTCN-3
74
+ - TypeScript (With TSX)
75
+ - VueJS
76
+ - Zig
76
77
 
77
78
  By default lizard will search for any source code that it knows and mix
78
79
  all the results together. This might not be what you want. You can use
@@ -160,7 +161,7 @@ Options
160
161
  search for all languages it knows. `lizard -l cpp -l java`searches for
161
162
  C++ and Java code. The available languages are: cpp, java, csharp,
162
163
  javascript, python, objectivec, ttcn, ruby, php, swift, scala, GDScript,
163
- go, lua, rust, typescript
164
+ go, lua, rust, typescript, plsql
164
165
  -V, --verbose Output in verbose mode (long function name)
165
166
  -C CCN, --CCN CCN Threshold for cyclomatic complexity number warning. The default value is
166
167
  15. Functions with CCN bigger than it will generate warning
@@ -195,7 +196,7 @@ Options
195
196
  -X, --xml Generate XML in cppncss style instead of the tabular output. Useful to
196
197
  generate report in Jenkins server
197
198
  --csv Generate CSV output as a transform of the default output
198
- -H, --html Output HTML report
199
+ -H, --html Output HTML report with interactive DataTables (sortable, searchable, filterable)
199
200
  --checkstyle Generate Checkstyle XML output for integration with Jenkins and other tools
200
201
  -m, --modified Calculate modified cyclomatic complexity number , which count a
201
202
  switch/case with multiple cases as one CCN.
@@ -413,5 +414,14 @@ Lizard is also used as a plugin for fastlane to help check code complexity and s
413
414
  - `European research project FASTEN (Fine-grained Analysis of SofTware Ecosystems as Networks, <http://fasten-project.eu/)>`_
414
415
  - `for a quality analyzer <https://github.com/fasten-project/quality-analyzer>`_
415
416
 
417
+ How To Contribute
418
+ -----------------
419
+
420
+ Contributions are welcome. Please refer to the rules and development workflow in:
421
+
422
+ - https://github.com/terryyin/lizard/tree/master/.cursor/rules
423
+
424
+ These guidelines are usable by both AI assistants and human contributors — what works for AI works for "I" as well — to keep changes cohesive, simple, and well-tested.
425
+
416
426
 
417
427
 
@@ -55,6 +55,7 @@ lizard_languages/lua.py
55
55
  lizard_languages/objc.py
56
56
  lizard_languages/perl.py
57
57
  lizard_languages/php.py
58
+ lizard_languages/plsql.py
58
59
  lizard_languages/python.py
59
60
  lizard_languages/r.py
60
61
  lizard_languages/ruby.py
@@ -48,6 +48,12 @@ TEMPLATE = '''<!DOCTYPE HTML PUBLIC
48
48
  <head>
49
49
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
50
50
  <title>Code complexity report</title>
51
+ <!-- DataTables CSS -->
52
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
53
+ <!-- jQuery -->
54
+ <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
55
+ <!-- DataTables JS -->
56
+ <script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
51
57
  <style>
52
58
  h2
53
59
  {
@@ -88,6 +94,42 @@ TEMPLATE = '''<!DOCTYPE HTML PUBLIC
88
94
  font-family: sans-serif;
89
95
  white-space: nowrap;
90
96
  }
97
+ td.file-header
98
+ {
99
+ background-color: LightBlue;
100
+ font-weight: bold;
101
+ }
102
+ td.function-name
103
+ {
104
+ background-color: LightSteelBlue;
105
+ }
106
+ /* DataTables wrapper styling */
107
+ .dataTables_wrapper {
108
+ margin: 0 auto;
109
+ width: 95%;
110
+ }
111
+ /* Fallback styling if DataTables CSS doesn't load */
112
+ table#complexityTable {
113
+ border-collapse: collapse;
114
+ width: 95%;
115
+ margin: 0 auto;
116
+ }
117
+ table#complexityTable th {
118
+ background-color: #4CAF50;
119
+ color: white;
120
+ padding: 10px;
121
+ text-align: left;
122
+ border: 1px solid #ddd;
123
+ }
124
+ table#complexityTable td {
125
+ border: 1px solid #ddd;
126
+ }
127
+ table#complexityTable tr:nth-child(even) {
128
+ background-color: #f2f2f2;
129
+ }
130
+ table#complexityTable tr:hover {
131
+ background-color: #ddd;
132
+ }
91
133
  </style>
92
134
  </head>
93
135
  <body>
@@ -95,26 +137,29 @@ TEMPLATE = '''<!DOCTYPE HTML PUBLIC
95
137
 
96
138
  <center>
97
139
 
98
- <table>
140
+ <table id="complexityTable" class="display" style="width:100%">
141
+ <thead>
142
+ <tr>
143
+ <th>File</th>
144
+ <th>Function name</th>
145
+ <th>Cyclomatic complexity ({{ thresholds["cyclomatic_complexity"] }})</th>
146
+ <th>LOC ({{ thresholds["nloc"] }})</th>
147
+ <th>
148
+ {% if thresholds["token_count"] %}
149
+ Token count ({{ thresholds["token_count"] }})
150
+ {% else %}
151
+ Token count
152
+ {% endif %}
153
+ </th>
154
+ <th>Parameter count ({{ thresholds["parameter_count"] }})</th>
155
+ </tr>
156
+ </thead>
157
+ <tbody>
99
158
  {% for file in files %}
100
- <tr><td colspan="7" style="background-color:LightBlue;">
101
- Source file: <b>{{ file.filename }}</b></td></tr>
102
- {% if file.functions|length > 0 %}
103
- <tr><th>Function name</th><th></th><th>
104
- Cyclomatic complexity
105
- ({{ thresholds["cyclomatic_complexity"] }})
106
- </th><th>LOC ({{ thresholds["nloc"] }})</th><th>
107
- {% if thresholds["token_count"] %}
108
- Token count ({{ thresholds["token_count"] }})
109
- {% else %}
110
- Token count
111
- {% endif %}
112
- </th><th>Parameter count ({{ thresholds["parameter_count"] }})</th></tr>
113
- {% endif %}
114
159
  {% for func in file.functions %}
115
160
  <tr>
116
- <td style="background-color:LightSteelBlue">{{ func.name }}</td>
117
- <td></td>
161
+ <td>{{ file.filename }}</td>
162
+ <td class="function-name">{{ func.name }}</td>
118
163
  {% if func.cyclomatic_complexity > thresholds["cyclomatic_complexity"] %}
119
164
  <td class="greater-value">{{ func.cyclomatic_complexity }}</td>
120
165
  {% else %}
@@ -145,6 +190,7 @@ Cyclomatic complexity
145
190
  </tr>
146
191
  {% endfor %}
147
192
  {% endfor %}
193
+ </tbody>
148
194
  </table>
149
195
  <center>
150
196
 
@@ -154,6 +200,29 @@ Cyclomatic complexity
154
200
  <a href="http://www.lizard.ws/">Lizard</a> on {{ date }}
155
201
  </td></tr>
156
202
  </table>
203
+
204
+ <script>
205
+ // Gracefully degrade if CDN is unavailable
206
+ if (typeof jQuery !== 'undefined' && typeof jQuery.fn.dataTable !== 'undefined') {
207
+ $(document).ready(function() {
208
+ try {
209
+ $('#complexityTable').DataTable({
210
+ "pageLength": 25,
211
+ "order": [[2, "desc"]], // Sort by cyclomatic complexity descending by default
212
+ "columnDefs": [
213
+ { "type": "num", "targets": [2, 3, 4, 5] } // Ensure numeric sorting for metric columns
214
+ ]
215
+ });
216
+ } catch (e) {
217
+ console.warn('DataTables initialization failed. Displaying static table.', e);
218
+ }
219
+ });
220
+ } else {
221
+ // Fallback: Table will display as static HTML
222
+ console.info('DataTables not available. Displaying static HTML table.');
223
+ }
224
+ </script>
225
+
157
226
  </body>
158
227
  </html>
159
228
 
@@ -45,11 +45,43 @@ class LizardExtension(object): # pylint: disable=R0903
45
45
  else:
46
46
  indent_indicator = ';'
47
47
  for token in tokens:
48
- if token in loops:
48
+ # Handle opening parenthesis - start of condition
49
+ if token == '(':
50
+ reader.context.set_in_condition(True)
51
+ reader.context.increment_condition_depth()
52
+ reader.context.set_logical_operator_added(False) # Reset for new condition
53
+ # Handle closing parenthesis - end of condition
54
+ elif token == ')':
55
+ reader.context.decrement_condition_depth()
56
+ if reader.context.get_condition_depth() == 0:
57
+ reader.context.set_in_condition(False)
58
+ reader.context.set_logical_operator_added(False)
59
+
60
+ # Handle logical operators && and || within conditions
61
+ elif token in ('&&', '||'):
62
+ if reader.context.get_in_condition():
63
+ # Only add nesting depth for the first logical operator in a condition
64
+ # Subsequent && or || operators in the same condition don't add depth
65
+ if not reader.context.get_logical_operator_added():
66
+ l_depth = reader.context.add_nd_condition()
67
+ if not reader.context.get_loop_status():
68
+ reader.context.add_hidden_bracket_condition()
69
+ reader.context.loop_bracket_status()
70
+ reader.context.set_logical_operator_added(True)
71
+ else:
72
+ # Not in a condition, treat as regular nesting
73
+ l_depth = reader.context.add_nd_condition()
74
+ if not reader.context.get_loop_status():
75
+ reader.context.add_hidden_bracket_condition()
76
+ reader.context.loop_bracket_status()
77
+
78
+ # Handle other loop keywords (if, for, while, etc.)
79
+ elif token in loops and token not in ('&&', '||'):
49
80
  l_depth = reader.context.add_nd_condition()
50
81
  if not reader.context.get_loop_status():
51
82
  reader.context.add_hidden_bracket_condition()
52
83
  reader.context.loop_bracket_status()
84
+
53
85
  if token == loop_indicator:
54
86
  reader.context.loop_bracket_status()
55
87
  if token == bracket:
@@ -82,6 +114,7 @@ class NDFileInfoAddition(FileInfoBuilder):
82
114
  self.current_function.nesting_depth = 0
83
115
  self.current_function.hidden_bracket = 0
84
116
  self.current_function.bracket_loop = False
117
+ self.reset_condition_tracking()
85
118
 
86
119
  def add_hidden_bracket_condition(self, inc=1):
87
120
  self.current_function.hidden_bracket += inc
@@ -96,6 +129,33 @@ class NDFileInfoAddition(FileInfoBuilder):
96
129
  def get_loop_status(self):
97
130
  return self.current_function.bracket_loop
98
131
 
132
+ def set_in_condition(self, in_condition):
133
+ self.current_function.in_condition = in_condition
134
+
135
+ def get_in_condition(self):
136
+ return self.current_function.in_condition
137
+
138
+ def increment_condition_depth(self):
139
+ self.current_function.condition_depth += 1
140
+
141
+ def decrement_condition_depth(self):
142
+ if self.current_function.condition_depth > 0:
143
+ self.current_function.condition_depth -= 1
144
+
145
+ def get_condition_depth(self):
146
+ return self.current_function.condition_depth
147
+
148
+ def reset_condition_tracking(self):
149
+ self.current_function.in_condition = False
150
+ self.current_function.condition_depth = 0
151
+ self.current_function.logical_operator_added = False
152
+
153
+ def set_logical_operator_added(self, added):
154
+ self.current_function.logical_operator_added = added
155
+
156
+ def get_logical_operator_added(self):
157
+ return self.current_function.logical_operator_added
158
+
99
159
 
100
160
  def get_method(cls, name):
101
161
  """ python3 doesn't need the __func__ to get the func of the
@@ -127,6 +187,9 @@ def _init_nesting_depth_data(self, *_):
127
187
  self.max_nesting_depth = 0
128
188
  self.hidden_bracket = 0
129
189
  self.bracket_loop = False
190
+ self.in_condition = False # Track if we're inside a condition
191
+ self.condition_depth = 0 # Track nesting depth within conditions
192
+ self.logical_operator_added = False # Track if we've added nesting for logical operators in current condition
130
193
 
131
194
 
132
195
  patch(NDFileInfoAddition, FileInfoBuilder)
@@ -3,4 +3,4 @@
3
3
  #
4
4
  # pylint: disable=missing-docstring,invalid-name
5
5
 
6
- version = "1.18.0"
6
+ version = "1.19.0"
@@ -26,6 +26,7 @@ from .vue import VueReader
26
26
  from .perl import PerlReader
27
27
  from .st import StReader
28
28
  from .r import RReader
29
+ from .plsql import PLSQLReader
29
30
 
30
31
 
31
32
  def languages():
@@ -56,6 +57,7 @@ def languages():
56
57
  PerlReader,
57
58
  StReader,
58
59
  RReader,
60
+ PLSQLReader,
59
61
  ]
60
62
 
61
63
 
@@ -54,7 +54,7 @@ class CLikeReader(CodeReader, CCppCommentsMixin):
54
54
  elif macro.group(1) == 'include':
55
55
  yield "#include"
56
56
  yield macro.group(2) or "\"\""
57
- for _ in macro.group(2).splitlines()[1:]:
57
+ for _ in macro.group(2).split('\n')[1:]:
58
58
  yield '\n'
59
59
  else:
60
60
  yield token
@@ -138,7 +138,7 @@ class CodeReader:
138
138
  r"|\/\/" + _until_end +
139
139
  r"|\#" +
140
140
  r"|:=|::|\*\*" +
141
- r"|\<\s*\?(?:\s*extends\s+\w+)?\s*\>" +
141
+ r"|\<(?=(?:[^<>]*\?)+[^<>]*\>)(?:[\w\s,.?]|(?:extends))+\>" +
142
142
  r"|" + r"|".join(re.escape(s) for s in combined_symbols) +
143
143
  r"|\\\n" +
144
144
  r"|\n" +