From 4d6f36e241d2bbda3fa28fb32e60d534e87a7ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 22 Nov 2019 15:54:11 +0800 Subject: =?UTF-8?q?=E6=9B=B4=E6=96=B0=20hover?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-beta/src/core/hover/init.lua | 12 ++++++++++-- server-beta/src/core/hover/label.lua | 17 ++++++++++++++++ server-beta/src/core/hover/name.lua | 38 ++++++++++++++++++++++++++---------- server-beta/src/utility.lua | 18 +++++++++++++++++ server-beta/src/vm/getValue.lua | 30 ++++++++++++++++++++++------ server-beta/test.lua | 2 +- server-beta/test/hover/init.lua | 21 ++++++++++---------- 7 files changed, 109 insertions(+), 29 deletions(-) diff --git a/server-beta/src/core/hover/init.lua b/server-beta/src/core/hover/init.lua index 9de5f4da..b99c14b2 100644 --- a/server-beta/src/core/hover/init.lua +++ b/server-beta/src/core/hover/init.lua @@ -4,8 +4,6 @@ local vm = require 'vm' local getLabel = require 'core.hover.label' local function getHoverAsFunction(source) - local uri = guide.getRoot(source).uri - local text = files.getText(uri) local values = vm.getValue(source) local labels = {} for _, value in ipairs(values) do @@ -21,10 +19,20 @@ local function getHoverAsFunction(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 diff --git a/server-beta/src/core/hover/label.lua b/server-beta/src/core/hover/label.lua index da8a0c84..759938d2 100644 --- a/server-beta/src/core/hover/label.lua +++ b/server-beta/src/core/hover/label.lua @@ -1,6 +1,8 @@ local buildName = require 'core.hover.name' local buildArg = require 'core.hover.arg' local buildReturn = require 'core.hover.return' +local vm = require 'vm' +local util = require 'utility' local function asFunction(source) local name = buildName(source) @@ -12,8 +14,23 @@ local function asFunction(source) 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 literal == nil then + return ('local %s: %s'):format(name, type) + else + return ('local %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) end end diff --git a/server-beta/src/core/hover/name.lua b/server-beta/src/core/hover/name.lua index ef7fee02..9eb066fc 100644 --- a/server-beta/src/core/hover/name.lua +++ b/server-beta/src/core/hover/name.lua @@ -18,18 +18,36 @@ local function asMethod(source) return ('%s:%s'):format(node, method) end -return function (source) - local parent = source.parent - if not parent then - return '' +local function asField(source) + local class = vm.eachField(source.node, function (info) + if info.key == 's|type' 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 buildName(source) + if source.type == 'local' + or source.type == 'getlocal' + or source.type == 'setlocal' then + return asLocal(source) or '' end - if parent.type == 'local' - or parent.type == 'getlocal' - or parent.type == 'setlocal' then - return asLocal(parent) or '' + if source.type == 'setmethod' then + return asMethod(source) or '' end - if parent.type == 'setmethod' then - return asMethod(parent) or '' + if source.type == 'setfield' then + return asField(source) or '' + end + local parent = source.parent + if parent then + return buildName(parent) end return '' end + +return buildName diff --git a/server-beta/src/utility.lua b/server-beta/src/utility.lua index 055b35c6..c9defebc 100644 --- a/server-beta/src/utility.lua +++ b/server-beta/src/utility.lua @@ -431,4 +431,22 @@ function m.viewString(str, quo) end end +function m.viewLiteral(v) + local tp = type(v) + if tp == 'nil' then + return 'nil' + elseif tp == 'string' then + return m.viewString(v) + elseif tp == 'boolean' then + return tostring(v) + elseif tp == 'number' then + if isInteger(v) then + return tostring(v) + else + return formatNumber(v) + end + end + return nil +end + return m diff --git a/server-beta/src/vm/getValue.lua b/server-beta/src/vm/getValue.lua index 07ebe2a5..ee486a54 100644 --- a/server-beta/src/vm/getValue.lua +++ b/server-beta/src/vm/getValue.lua @@ -30,10 +30,26 @@ local function merge(t, b) end local function alloc(o) - return { - [1] = o, - [o] = true, - } + -- TODO + assert(o.type) + if type(o.type) == 'table' then + local values = {} + for i = 1, #o.type do + local sub = { + type = o.type[i], + value = o.value, + source = o.source, + } + values[i] = sub + values[sub] = true + end + return values + else + return { + [1] = o, + [o] = true, + } + end end local function insert(t, o) @@ -758,8 +774,10 @@ function vm.getLiteral(source, type) end for i = 1, #values do local v = values[i] - if v.type == type and v.value ~= nil then - return v.value + if v.value ~= nil then + if type == nil or v.type == type then + return v.value + end end end return nil diff --git a/server-beta/test.lua b/server-beta/test.lua index dffae940..dc1023d6 100644 --- a/server-beta/test.lua +++ b/server-beta/test.lua @@ -42,7 +42,7 @@ local function main() test 'highlight' test 'rename' test 'type_inference' - --test 'hover' + test 'hover' --test 'completion' --test 'signature' --test 'document_symbol' diff --git a/server-beta/test/hover/init.lua b/server-beta/test/hover/init.lua index 8ecf226e..458adc8c 100644 --- a/server-beta/test/hover/init.lua +++ b/server-beta/test/hover/init.lua @@ -125,34 +125,35 @@ obj.() ]] "function obj.xxx()" -TEST [[ -obj.() -]] -[[function obj.xxx() - -> any -]] +-- 不不同调用方式推断定义 +--TEST [[ +--obj.() +--]] +--[[function obj.xxx() +-- -> any +--]] TEST [[ local = 1 ]] -"local x: number = 1" +"local x: integer = 1" TEST [[ = 1 ]] -"global x: number = 1" +"global x: integer = 1" TEST [[ local t = {} t. = 1 ]] -"field t.x: number = 1" +"field t.x: integer = 1" TEST [[ t = {} t. = 1 ]] -"global t.x: number = 1" +"global t.x: integer = 1" TEST [[ local mt = {} -- cgit v1.2.3