1
Jianw
9 天以前 70f29da38121b9a467841253e3268feb5df02902
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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