diff options
Diffstat (limited to 'script-beta/src/core/hover')
-rw-r--r-- | script-beta/src/core/hover/arg.lua | 20 | ||||
-rw-r--r-- | script-beta/src/core/hover/init.lua | 56 | ||||
-rw-r--r-- | script-beta/src/core/hover/label.lua | 103 | ||||
-rw-r--r-- | script-beta/src/core/hover/name.lua | 64 | ||||
-rw-r--r-- | script-beta/src/core/hover/return.lua | 34 | ||||
-rw-r--r-- | script-beta/src/core/hover/table.lua | 35 |
6 files changed, 312 insertions, 0 deletions
diff --git a/script-beta/src/core/hover/arg.lua b/script-beta/src/core/hover/arg.lua new file mode 100644 index 00000000..be344488 --- /dev/null +++ b/script-beta/src/core/hover/arg.lua @@ -0,0 +1,20 @@ +local guide = require 'parser.guide' +local vm = require 'vm' + +local function asFunction(source) + if not source.args then + return '' + end + local args = {} + for i = 1, #source.args do + local arg = source.args[i] + args[i] = ('%s: %s'):format(guide.getName(arg), vm.getType(arg)) + end + return table.concat(args, ', ') +end + +return function (source) + if source.type == 'function' then + return asFunction(source) + end +end diff --git a/script-beta/src/core/hover/init.lua b/script-beta/src/core/hover/init.lua new file mode 100644 index 00000000..b99c14b2 --- /dev/null +++ b/script-beta/src/core/hover/init.lua @@ -0,0 +1,56 @@ +local files = require 'files' +local guide = require 'parser.guide' +local vm = require 'vm' +local getLabel = require 'core.hover.label' + +local function getHoverAsFunction(source) + local values = vm.getValue(source) + local labels = {} + for _, value in ipairs(values) do + if value.type == 'function' then + labels[#labels+1] = getLabel(value.source) + end + end + + local label = table.concat(labels, '\n') + return { + label = label, + source = source, + } +end + +local function getHoverAsValue(source) + local label = getLabel(source) + return { + label = label, + source = source, + } +end + +local function getHover(source) + local isFunction = vm.hasType(source, 'function') + if isFunction then + return getHoverAsFunction(source) + else + return getHoverAsValue(source) + end +end + +return function (uri, offset) + local ast = files.getAst(uri) + if not ast then + return nil + end + local hover = guide.eachSourceContain(ast.ast, offset, function (source) + if source.type == 'local' + or source.type == 'setlocal' + or source.type == 'getlocal' + or source.type == 'setglobal' + or source.type == 'getglobal' + or source.type == 'field' + or source.type == 'method' then + return getHover(source) + end + end) + return hover +end diff --git a/script-beta/src/core/hover/label.lua b/script-beta/src/core/hover/label.lua new file mode 100644 index 00000000..72ce60f4 --- /dev/null +++ b/script-beta/src/core/hover/label.lua @@ -0,0 +1,103 @@ +local buildName = require 'core.hover.name' +local buildArg = require 'core.hover.arg' +local buildReturn = require 'core.hover.return' +local buildTable = require 'core.hover.table' +local vm = require 'vm' +local util = require 'utility' + +local function asFunction(source) + local name = buildName(source) + local arg = buildArg(source) + local rtn = buildReturn(source) + local lines = {} + lines[1] = ('function %s(%s)'):format(name, arg) + lines[2] = rtn + return table.concat(lines, '\n') +end + +local function asLocal(source) + local name = buildName(source) + local type = vm.getType(source) + local literal = vm.getLiteral(source) + if type == 'table' then + type = buildTable(source) + end + if literal == nil then + return ('local %s: %s'):format(name, type) + else + return ('local %s: %s = %s'):format(name, type, util.viewLiteral(literal)) + end +end + +local function asGlobal(source) + local name = buildName(source) + local type = vm.getType(source) + local literal = vm.getLiteral(source) + if type == 'table' then + type = buildTable(source) + end + if literal == nil then + return ('global %s: %s'):format(name, type) + else + return ('global %s: %s = %s'):format(name, type, util.viewLiteral(literal)) + end +end + +local function isGlobalField(source) + if source.type == 'field' + or source.type == 'method' then + source = source.parent + end + if source.type == 'setfield' + or source.type == 'getfield' + or source.type == 'setmethod' + or source.type == 'getmethod' + or source.type == 'tablefield' then + local node = source.node + if node.type == 'setglobal' + or node.type == 'getglobal' then + return true + end + return isGlobalField(node) + else + return false + end +end + +local function asField(source) + if isGlobalField(source) then + return asGlobal(source) + end + local name = buildName(source) + local type = vm.getType(source) + local literal = vm.getLiteral(source) + if type == 'table' then + type = buildTable(source) + end + if literal == nil then + return ('field %s: %s'):format(name, type) + else + return ('field %s: %s = %s'):format(name, type, util.viewLiteral(literal)) + end +end + +return function (source) + if source.type == 'function' then + return asFunction(source) + elseif source.type == 'local' + or source.type == 'getlocal' + or source.type == 'setlocal' then + return asLocal(source) + elseif source.type == 'setglobal' + or source.type == 'getglobal' then + return asGlobal(source) + elseif source.type == 'getfield' + or source.type == 'setfield' + or source.type == 'getmethod' + or source.type == 'setmethod' + or source.type == 'tablefield' + or source.type == 'field' + or source.type == 'method' then + return asField(source) + end +end diff --git a/script-beta/src/core/hover/name.lua b/script-beta/src/core/hover/name.lua new file mode 100644 index 00000000..a22a8b5a --- /dev/null +++ b/script-beta/src/core/hover/name.lua @@ -0,0 +1,64 @@ +local guide = require 'parser.guide' +local vm = require 'vm' + +local function asLocal(source) + return guide.getName(source) +end + +local function asMethod(source) + local class = vm.eachField(source.node, function (info) + if info.key == 's|type' or info.key == 's|__name' or info.key == 's|name' then + if info.value and info.value.type == 'string' then + return info.value[1] + end + end + end) + local node = class or guide.getName(source.node) or '?' + local method = guide.getName(source) + return ('%s:%s'):format(node, method) +end + +local function asField(source) + local class = vm.eachField(source.node, function (info) + if info.key == 's|type' or info.key == 's|__name' or info.key == 's|name' then + if info.value and info.value.type == 'string' then + return info.value[1] + end + end + end) + local node = class or guide.getName(source.node) or '?' + local method = guide.getName(source) + return ('%s.%s'):format(node, method) +end + +local function asGlobal(source) + return guide.getName(source) +end + +local function buildName(source) + if source.type == 'local' + or source.type == 'getlocal' + or source.type == 'setlocal' then + return asLocal(source) or '' + end + if source.type == 'setglobal' + or source.type == 'getglobal' then + return asGlobal(source) or '' + end + if source.type == 'setmethod' + or source.type == 'getmethod' then + return asMethod(source) or '' + end + if source.type == 'setfield' + or source.tyoe == 'getfield' + or source.type == 'tablefield' then + return asField(source) or '' + end + local parent = source.parent + if parent then + return buildName(parent) + end + return '' +end + +return buildName diff --git a/script-beta/src/core/hover/return.lua b/script-beta/src/core/hover/return.lua new file mode 100644 index 00000000..c22626a6 --- /dev/null +++ b/script-beta/src/core/hover/return.lua @@ -0,0 +1,34 @@ +local guide = require 'parser.guide' +local vm = require 'vm' + +local function asFunction(source) + if not source.returns then + return nil + end + local returns = {} + for _, rtn in ipairs(source.returns) do + for i = 1, #rtn do + local values = vm.getValue(rtn[i]) + returns[#returns+1] = values + end + break + end + if #returns == 0 then + return nil + end + local lines = {} + for i = 1, #returns do + if i == 1 then + lines[i] = (' -> %s'):format(vm.viewType(returns[i])) + else + lines[i] = ('% 3d. %s'):format(i, returns[i]) + end + end + return table.concat(lines, '\n') +end + +return function (source) + if source.type == 'function' then + return asFunction(source) + end +end diff --git a/script-beta/src/core/hover/table.lua b/script-beta/src/core/hover/table.lua new file mode 100644 index 00000000..9ed86692 --- /dev/null +++ b/script-beta/src/core/hover/table.lua @@ -0,0 +1,35 @@ +local vm = require 'vm' + +local function checkClass(source) +end + +return function (source) + local fields = {} + local class + vm.eachField(source, function (info) + if info.key == 's|type' or info.key == 's|__name' or info.key == 's|name' then + if info.value and info.value.type == 'string' then + class = info.value[1] + end + end + local type = vm.getType(info.source) + fields[#fields+1] = ('%s'):format(type) + end) + local fieldsBuf + if #fields == 0 then + fieldsBuf = '{}' + else + local lines = {} + lines[#lines+1] = '{' + for _, field in ipairs(fields) do + lines[#lines+1] = ' ' .. field + end + lines[#lines+1] = '}' + fieldsBuf = table.concat(lines, '\n') + end + if class then + return ('%s %s'):format(class, fieldsBuf) + else + return fieldsBuf + end +end |