• 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

94.39
/src/luacheck/serializer.lua
1
local parse_inline_options = require "luacheck.stages.parse_inline_options"
780✔
2
local stages = require "luacheck.stages"
780✔
3
local utils = require "luacheck.utils"
780✔
4

5
local serializer = {}
780✔
6

7
local option_fields = {
780✔
8
   "ignore", "std", "globals", "unused_args", "self", "compat", "global", "unused", "redefined",
520✔
9
   "unused_secondaries", "allow_defined", "allow_defined_top", "module",
520✔
10
   "read_globals", "new_globals", "new_read_globals", "enable", "only", "not_globals",
520✔
11
   "max_line_length", "max_code_line_length", "max_string_line_length", "max_comment_line_length",
520✔
12
   "max_cyclomatic_complexity", "operators"
520✔
13
}
520✔
14

15
local function compress_table(t, fields)
16
   local res = {}
684✔
17

18
   for index, field in ipairs(fields) do
6,828✔
19
      local value = t[field]
6,144✔
20

21
      if value ~= nil then
6,144✔
22
         if field == "options" then
1,458✔
23
            value = compress_table(value, option_fields)
×
24
         end
25

26
         res[index] = value
1,458✔
27
      end
28
   end
29

30
   return res
684✔
31
end
32

33
local function compress_tables(tables, per_code_fields)
34
   local res = {}
84✔
35

36
   for _, t in ipairs(tables) do
768✔
37
      local fields = per_code_fields and stages.warnings[t.code].fields or parse_inline_options.inline_option_fields
684✔
38
      table.insert(res, compress_table(t, fields))
912✔
39
   end
40

41
   return res
84✔
42
end
43

44
local function compress_result(result)
45
   local res = {}
42✔
46
   res[1] = compress_tables(result.warnings, true)
56✔
47
   res[2] = compress_tables(result.inline_options)
56✔
48
   res[3] = result.line_lengths
42✔
49
   res[4] = result.line_endings
42✔
50
   return res
42✔
51
end
52

53
local function decompress_table(t, fields)
54
   local res = {}
6✔
55

56
   for index, field in ipairs(fields) do
60✔
57
      local value = t[index]
54✔
58

59
      if value ~= nil then
54✔
60
         if field == "options" then
6✔
61
            value = decompress_table(value, option_fields)
×
62
         end
63

64
         res[field] = value
6✔
65
      end
66
   end
67

68
   return res
6✔
69
end
70

71
local function decompress_tables(tables, per_code_fields)
72
   local res = {}
12✔
73

74
   for _, t in ipairs(tables) do
18✔
75
      local fields
76

77
      if per_code_fields then
6✔
78
         fields = stages.warnings[t[1]].fields
6✔
79
      else
80
         fields = parse_inline_options.inline_option_fields
×
81
      end
82

83
      table.insert(res, decompress_table(t, fields))
8✔
84
   end
85

86
   return res
12✔
87
end
88

89
local function decompress_result(compressed)
90
   local result = {}
6✔
91
   result.warnings = decompress_tables(compressed[1], true)
8✔
92
   result.inline_options = decompress_tables(compressed[2])
8✔
93
   result.line_lengths = compressed[3]
6✔
94
   result.line_endings = compressed[4]
6✔
95
   return result
6✔
96
end
97

98
local function get_local_name(index)
99
   return string.char(index + (index > 26 and 70 or 64))
648✔
100
end
101

102
local function max_n(t)
103
   local res = 0
852✔
104

105
   for k in pairs(t) do
3,120✔
106
      res = math.max(res, k)
2,268✔
107
   end
108

109
   return res
852✔
110
end
111

112
-- Serializes a value into buffer.
113
-- `strings` is a table mapping string values to where they first occurred or to name of local
114
-- variable used to represent it.
115
-- Array part contains representations of values saved into locals.
116
local function add_value(buffer, strings, value, level)
117
   if type(value) == "string" then
2,310✔
118
      local prev = strings[value]
1,368✔
119

120
      if type(prev) == "string" then
1,368✔
121
         -- There is a local with such value.
122
         table.insert(buffer, prev)
624✔
123
      elseif type(prev) == "number" and #strings < 52 then
744✔
124
         -- Value is used second time, put it into a local.
125
         table.insert(strings, ("%q"):format(value))
324✔
126
         local local_name = get_local_name(#strings)
324✔
127
         buffer[prev] = local_name
324✔
128
         table.insert(buffer, local_name)
324✔
129
         strings[value] = local_name
324✔
130
      else
131
         table.insert(buffer, ("%q"):format(value))
420✔
132
         strings[value] = #buffer
420✔
133
      end
134
   elseif type(value) == "table" then
942✔
135
      -- Level 1 has the result, level 2 has warning/inline option/line info arrays,
136
      -- level 3 has warnings/inline option containers, level 4 has inline options.
137
      local allow_sparse = level ~= 3
852✔
138
      local nil_tail_start
139
      local is_sparse
140
      local put_one
141
      table.insert(buffer, "{")
852✔
142

143
      for index = 1, max_n(value) do
5,360✔
144
         local item = value[index]
4,224✔
145

146
         if item == nil then
4,224✔
147
            is_sparse = allow_sparse
1,956✔
148
            nil_tail_start = nil_tail_start or index
1,956✔
149
         else
150
            if put_one then
2,268✔
151
               table.insert(buffer, ",")
1,506✔
152
            end
153

154
            if is_sparse then
2,268✔
155
               table.insert(buffer, ("[%d]="):format(index))
×
156
            elseif nil_tail_start then
2,268✔
157
               for _ = nil_tail_start, index - 1 do
2,640✔
158
                  table.insert(buffer, "nil,")
1,956✔
159
               end
160

161
               nil_tail_start = nil
684✔
162
            end
163

164
            add_value(buffer, strings, item, level + 1)
2,268✔
165
            put_one = true
2,268✔
166
         end
167
      end
168

169
      table.insert(buffer, "}")
852✔
170
   else
171
      table.insert(buffer, tostring(value))
90✔
172
   end
173
end
174

175
-- Serializes check result, returns a string.
176
function serializer.dump_check_result(result)
780✔
177
   local strings = {}
42✔
178
   local buffer = {"", "return "}
42✔
179
   add_value(buffer, strings, compress_result(result), 1)
56✔
180

181
   if strings[1] then
42✔
182
      local names = {}
12✔
183

184
      for index in ipairs(strings) do
336✔
185
         table.insert(names, get_local_name(index))
432✔
186
      end
187

188
      buffer[1] = "local " .. table.concat(names, ",") .. "=" .. table.concat(strings, ",") .. ";"
12✔
189
   end
190

191
   return table.concat(buffer)
42✔
192
end
193

194
-- Loads check result from a string, returns check result table or nothing on error.
195
function serializer.load_check_result(dumped)
780✔
196
   local func = utils.load(dumped, {})
6✔
197

198
   if not func then
6✔
199
      return
×
200
   end
201

202
   local ok, compressed_result = pcall(func)
6✔
203

204
   if not ok or type(compressed_result) ~= "table" then
6✔
205
      return
×
206
   end
207

208
   return decompress_result(compressed_result)
6✔
209
end
210

211
return serializer
780✔
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