local core_utils = require "luacheck.core_utils"
|
|
local stage = {}
|
|
local function unused_field_value_message_format(warning)
|
local target = warning.index and "index" or "field"
|
return "value assigned to " .. target .. " {field!} is overwritten on line {overwritten_line} before use"
|
end
|
|
stage.warnings = {
|
["314"] = {message_format = unused_field_value_message_format,
|
fields = {"field", "index", "overwritten_line","overwritten_column", "overwritten_end_column"}}
|
}
|
|
local function warn_unused_field_value(chstate, node, field_repr, is_index, overwriting_node)
|
chstate:warn_range("314", node, {
|
field = field_repr,
|
index = is_index,
|
overwritten_line = overwriting_node.line,
|
overwritten_column = chstate:offset_to_column(overwriting_node.line, overwriting_node.offset),
|
overwritten_end_column = chstate:offset_to_column(overwriting_node.line, overwriting_node.end_offset)
|
})
|
end
|
|
local function check_table(chstate, node)
|
local array_index = 1.0
|
local key_value_to_node = {}
|
local key_node_to_repr = {}
|
local index_key_nodes = {}
|
|
for _, pair in ipairs(node) do
|
local key_value
|
local key_repr
|
local key_node
|
|
if pair.tag == "Pair" then
|
key_node = pair[1]
|
key_value, key_repr = core_utils.eval_const_node(key_node)
|
else
|
key_node = pair
|
key_value = array_index
|
key_repr = tostring(math.floor(key_value))
|
array_index = array_index + 1.0
|
end
|
|
if key_value then
|
local prev_key_node = key_value_to_node[key_value]
|
local prev_key_repr = key_node_to_repr[prev_key_node]
|
local prev_key_is_index = index_key_nodes[prev_key_node]
|
|
if prev_key_node then
|
warn_unused_field_value(chstate, prev_key_node, prev_key_repr, prev_key_is_index, key_node)
|
end
|
|
key_value_to_node[key_value] = key_node
|
key_node_to_repr[key_node] = key_repr
|
|
if pair.tag ~= "Pair" then
|
index_key_nodes[key_node] = true
|
end
|
end
|
end
|
end
|
|
local function check_nodes(chstate, nodes)
|
for _, node in ipairs(nodes) do
|
if type(node) == "table" then
|
if node.tag == "Table" then
|
check_table(chstate, node)
|
end
|
|
check_nodes(chstate, node)
|
end
|
end
|
end
|
|
function stage.run(chstate)
|
check_nodes(chstate, chstate.ast)
|
end
|
|
return stage
|