summaryrefslogtreecommitdiff
path: root/script-beta/core/hover/table.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script-beta/core/hover/table.lua')
-rw-r--r--script-beta/core/hover/table.lua257
1 files changed, 0 insertions, 257 deletions
diff --git a/script-beta/core/hover/table.lua b/script-beta/core/hover/table.lua
deleted file mode 100644
index 02be5271..00000000
--- a/script-beta/core/hover/table.lua
+++ /dev/null
@@ -1,257 +0,0 @@
-local vm = require 'vm'
-local util = require 'utility'
-local guide = require 'parser.guide'
-local config = require 'config'
-local lang = require 'language'
-
-local function getKey(src)
- local key = vm.getKeyName(src)
- if not key or #key <= 2 then
- if not src.index then
- return '[any]'
- end
- local class = vm.getClass(src.index)
- if class then
- return ('[%s]'):format(class)
- end
- local tp = vm.getInferType(src.index)
- if tp then
- return ('[%s]'):format(tp)
- end
- return '[any]'
- end
- local ktype = key:sub(1, 2)
- key = key:sub(3)
- if ktype == 's|' then
- if key:match '^[%a_][%w_]*$' then
- return key
- else
- return ('[%s]'):format(util.viewLiteral(key))
- end
- end
- return ('[%s]'):format(key)
-end
-
-local function getFieldFast(src)
- local value = guide.getObjectValue(src) or src
- if not value then
- return 'any'
- end
- if value.type == 'boolean' then
- return value.type, util.viewLiteral(value[1])
- end
- if value.type == 'number'
- or value.type == 'integer' then
- if math.tointeger(value[1]) then
- if config.config.runtime.version == 'Lua 5.3'
- or config.config.runtime.version == 'Lua 5.4' then
- return 'integer', util.viewLiteral(value[1])
- end
- end
- return value.type, util.viewLiteral(value[1])
- end
- if value.type == 'table'
- or value.type == 'function' then
- return value.type
- end
- if value.type == 'string' then
- local literal = value[1]
- if type(literal) == 'string' and #literal >= 50 then
- literal = literal:sub(1, 47) .. '...'
- end
- return value.type, util.viewLiteral(literal)
- end
-end
-
-local function getFieldFull(src)
- local tp = vm.getInferType(src)
- --local class = vm.getClass(src)
- local literal = vm.getInferLiteral(src)
- if type(literal) == 'string' and #literal >= 50 then
- literal = literal:sub(1, 47) .. '...'
- end
- return tp, literal
-end
-
-local function getField(src, timeUp, mark, key)
- if src.type == 'table'
- or src.type == 'function' then
- return nil
- end
- if src.parent then
- if src.type == 'string'
- or src.type == 'boolean'
- or src.type == 'number'
- or src.type == 'integer' then
- if src.parent.type == 'tableindex'
- or src.parent.type == 'setindex'
- or src.parent.type == 'getindex' then
- if src.parent.index == src then
- src = src.parent
- end
- end
- end
- end
- local tp, literal
- tp, literal = getFieldFast(src)
- if tp then
- return tp, literal
- end
- if timeUp or mark[key] then
- return nil
- end
- mark[key] = true
- tp, literal = getFieldFull(src)
- if tp then
- return tp, literal
- end
- return nil
-end
-
-local function buildAsHash(classes, literals)
- local keys = {}
- for k in pairs(classes) do
- keys[#keys+1] = k
- end
- table.sort(keys)
- local lines = {}
- lines[#lines+1] = '{'
- for _, key in ipairs(keys) do
- local class = classes[key]
- local literal = literals[key]
- if literal then
- lines[#lines+1] = (' %s: %s = %s,'):format(key, class, literal)
- else
- lines[#lines+1] = (' %s: %s,'):format(key, class)
- end
- end
- lines[#lines+1] = '}'
- return table.concat(lines, '\n')
-end
-
-local function buildAsConst(classes, literals)
- local keys = {}
- for k in pairs(classes) do
- keys[#keys+1] = k
- end
- table.sort(keys, function (a, b)
- return tonumber(literals[a]) < tonumber(literals[b])
- end)
- local lines = {}
- lines[#lines+1] = '{'
- for _, key in ipairs(keys) do
- local class = classes[key]
- local literal = literals[key]
- if literal then
- lines[#lines+1] = (' %s: %s = %s,'):format(key, class, literal)
- else
- lines[#lines+1] = (' %s: %s,'):format(key, class)
- end
- end
- lines[#lines+1] = '}'
- return table.concat(lines, '\n')
-end
-
-local function mergeLiteral(literals)
- local results = {}
- local mark = {}
- for _, value in ipairs(literals) do
- if not mark[value] then
- mark[value] = true
- results[#results+1] = value
- end
- end
- if #results == 0 then
- return nil
- end
- table.sort(results)
- return table.concat(results, '|')
-end
-
-local function mergeTypes(types)
- local results = {}
- local mark = {
- -- 讲道理table的keyvalue不会是nil
- ['nil'] = true,
- }
- for _, tv in ipairs(types) do
- for tp in tv:gmatch '[^|]+' do
- if not mark[tp] then
- mark[tp] = true
- results[#results+1] = tp
- end
- end
- end
- return guide.mergeTypes(results)
-end
-
-local function clearClasses(classes)
- classes['[nil]'] = nil
- classes['[any]'] = nil
- classes['[string]'] = nil
-end
-
-return function (source)
- local literals = {}
- local classes = {}
- local clock = os.clock()
- local timeUp
- local mark = {}
- local fields = vm.getFields(source, 'deep')
- local keyCount = 0
- for _, src in ipairs(fields) do
- local key = getKey(src)
- if not key then
- goto CONTINUE
- end
- if not classes[key] then
- classes[key] = {}
- keyCount = keyCount + 1
- end
- if not literals[key] then
- literals[key] = {}
- end
- if not TEST and os.clock() - clock > config.config.hover.fieldInfer / 1000.0 then
- timeUp = true
- end
- local class, literal = getField(src, timeUp, mark, key)
- if literal == 'nil' then
- literal = nil
- end
- classes[key][#classes[key]+1] = class
- literals[key][#literals[key]+1] = literal
- if keyCount >= 1000 then
- break
- end
- ::CONTINUE::
- end
-
- clearClasses(classes)
-
- for key, class in pairs(classes) do
- literals[key] = mergeLiteral(literals[key])
- classes[key] = mergeTypes(class)
- end
-
- if not next(classes) then
- return '{}'
- end
-
- local intValue = true
- for key, class in pairs(classes) do
- if class ~= 'integer' or not tonumber(literals[key]) then
- intValue = false
- break
- end
- end
- local result
- if intValue then
- result = buildAsConst(classes, literals)
- else
- result = buildAsHash(classes, literals)
- end
- if timeUp then
- result = ('\n--%s\n%s'):format(lang.script.HOVER_TABLE_TIME_UP, result)
- end
- return result
-end