• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lunarmodules / luacheck / 24662353255

20 Apr 2026 10:48AM UTC coverage: 97.095% (+0.07%) from 97.027%
24662353255

push

github

web-flow
fix(ci): build LuaJIT using system malloc for lualanes tests (#144)

6318 of 6507 relevant lines covered (97.1%)

26928.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/luacheck/stages/detect_cyclomatic_complexity.lua
1
local utils = require "luacheck.utils"
870✔
2

3
local stage = {}
870✔
4

5
local function cyclomatic_complexity_message_format(warning)
6
   local template = "cyclomatic complexity of %s is too high ({complexity} > {max_complexity})"
24✔
7

8
   local function_descr
9

10
   if warning.function_type == "main_chunk" then
24✔
11
      function_descr = "main chunk"
6✔
12
   elseif warning.function_name then
18✔
13
      function_descr = "{function_type} {function_name!}"
12✔
14
   else
15
      function_descr = "function"
6✔
16
   end
17

18
   return template:format(function_descr)
24✔
19
end
20

21
stage.warnings = {
870✔
22
   ["561"] = {message_format = cyclomatic_complexity_message_format,
870✔
23
      fields = {"complexity", "function_type", "function_name"}}
870✔
24
}
870✔
25

26
local function warn_cyclomatic_complexity(chstate, line, complexity)
27
   if line == chstate.top_line then
2,736✔
28
      chstate:warn("561", 1, 1, 1, {
2,484✔
29
         complexity = complexity,
1,242✔
30
         function_type = "main_chunk"
828✔
31
      })
1,242✔
32
   else
33
      local node = line.node
1,494✔
34

35
      chstate:warn_range("561", node, {
2,988✔
36
         complexity = complexity,
1,494✔
37
         function_type = node[1][1] and node[1][1].implicit and "method" or "function",
1,494✔
38
         function_name = node.name
1,494✔
39
      })
40
   end
41
end
42

43
local CyclomaticComplexityMetric = utils.class()
870✔
44

45
function CyclomaticComplexityMetric:incr_decisions(count)
870✔
46
   self.count = self.count + count
2,070✔
47
end
48

49
function CyclomaticComplexityMetric:calc_expr(node)
870✔
50
   if node.tag == "Op" and (node[1] == "and" or node[1] == "or") then
26,808✔
51
      self:incr_decisions(1)
642✔
52
   end
53

54
   if node.tag ~= "Function" then
26,808✔
55
      self:calc_exprs(node)
25,320✔
56
   end
57
end
58

59
function CyclomaticComplexityMetric:calc_exprs(exprs)
870✔
60
   for _, expr in ipairs(exprs) do
69,510✔
61
      if type(expr) == "table" then
39,912✔
62
         self:calc_expr(expr)
21,882✔
63
      end
64
   end
65
end
66

67
function CyclomaticComplexityMetric:calc_item_Eval(item)
870✔
68
   self:calc_expr(item.node)
4,926✔
69
end
70

71
function CyclomaticComplexityMetric:calc_item_Local(item)
870✔
72
   if item.rhs then
5,340✔
73
      self:calc_exprs(item.rhs)
1,866✔
74
   end
75
end
76

77
function CyclomaticComplexityMetric:calc_item_Set(item)
870✔
78
   self:calc_exprs(item.rhs)
2,412✔
79
end
80

81
function CyclomaticComplexityMetric:calc_item(item)
870✔
82
   local f = self["calc_item_" .. item.tag]
21,096✔
83
   if f then
21,096✔
84
      f(self, item)
12,678✔
85
   end
86
end
87

88
function CyclomaticComplexityMetric:calc_items(items)
870✔
89
   for _, item in ipairs(items) do
23,832✔
90
      self:calc_item(item)
21,096✔
91
   end
92
end
93

94
-- stmt if: {condition, block; condition, block; ... else_block}
95
function CyclomaticComplexityMetric:calc_stmt_If(node)
870✔
96
   for i = 1, #node - 1, 2 do
1,722✔
97
      self:incr_decisions(1)
924✔
98
      self:calc_stmts(node[i+1])
924✔
99
   end
100

101
   if #node % 2 == 1 then
798✔
102
      self:calc_stmts(node[#node])
294✔
103
   end
104
end
105

106
-- stmt while: {condition, block}
107
function CyclomaticComplexityMetric:calc_stmt_While(node)
870✔
108
   self:incr_decisions(1)
96✔
109
   self:calc_stmts(node[2])
96✔
110
end
111

112
-- stmt repeat: {block, condition}
113
function CyclomaticComplexityMetric:calc_stmt_Repeat(node)
870✔
114
   self:incr_decisions(1)
42✔
115
   self:calc_stmts(node[1])
42✔
116
end
117

118
-- stmt forin: {iter_vars, expression_list, block}
119
function CyclomaticComplexityMetric:calc_stmt_Forin(node)
870✔
120
   self:incr_decisions(1)
222✔
121
   self:calc_stmts(node[3])
222✔
122
end
123

124
-- stmt fornum: {first_var, expression, expression, expression[optional], block}
125
function CyclomaticComplexityMetric:calc_stmt_Fornum(node)
870✔
126
   self:incr_decisions(1)
144✔
127
   self:calc_stmts(node[5] or node[4])
144✔
128
end
129

130
function CyclomaticComplexityMetric:calc_stmt(node)
870✔
131
   local f = self["calc_stmt_" .. node.tag]
9,288✔
132
   if f then
9,288✔
133
      f(self, node)
1,302✔
134
   end
135
end
136

137
function CyclomaticComplexityMetric:calc_stmts(stmts)
870✔
138
   for _, stmt in ipairs(stmts) do
13,746✔
139
      self:calc_stmt(stmt)
9,288✔
140
   end
141
end
142

143
-- Cyclomatic complexity of a function equals to the number of decision points plus 1.
144
function CyclomaticComplexityMetric:report(chstate, line)
870✔
145
   self.count = 1
2,736✔
146
   self:calc_stmts(line.node[2])
2,736✔
147
   self:calc_items(line.items)
2,736✔
148
   warn_cyclomatic_complexity(chstate, line, self.count)
2,736✔
149
end
150

151
function stage.run(chstate)
870✔
152
   local ccmetric = CyclomaticComplexityMetric()
1,242✔
153

154
   for _, line in ipairs(chstate.lines) do
3,978✔
155
      ccmetric:report(chstate, line)
2,736✔
156
   end
157
end
158

159
return stage
870✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc