summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-11-20 21:44:35 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-11-20 21:44:35 +0800
commit6a2ee814158b5e343a8b1f63a26b4de40e29ae2a (patch)
tree8e3b96cd763145dbefae80e94645080732c1ba95
parentaa710d07d78bb3b908543ec657c93b5672681699 (diff)
downloadlua-language-server-6a2ee814158b5e343a8b1f63a26b4de40e29ae2a.zip
支持 library
-rw-r--r--server-beta/src/vm/dummySource.lua13
-rw-r--r--server-beta/src/vm/getLibrary.lua75
-rw-r--r--server-beta/src/vm/getValue.lua48
-rw-r--r--server-beta/src/vm/init.lua1
-rw-r--r--server-beta/test/type_inference/init.lua4
5 files changed, 101 insertions, 40 deletions
diff --git a/server-beta/src/vm/dummySource.lua b/server-beta/src/vm/dummySource.lua
new file mode 100644
index 00000000..50ff13e7
--- /dev/null
+++ b/server-beta/src/vm/dummySource.lua
@@ -0,0 +1,13 @@
+local vm = require 'vm.vm'
+
+vm.librarySourceCache = setmetatable({}, { __mode = 'kv'})
+
+function vm.librarySource(lib)
+ if not vm.librarySourceCache[lib] then
+ vm.librarySourceCache[lib] = {
+ type = 'library',
+ library = lib,
+ }
+ end
+ return vm.librarySourceCache[lib]
+end
diff --git a/server-beta/src/vm/getLibrary.lua b/server-beta/src/vm/getLibrary.lua
index 08f015a6..d2645790 100644
--- a/server-beta/src/vm/getLibrary.lua
+++ b/server-beta/src/vm/getLibrary.lua
@@ -13,34 +13,63 @@ local function checkStdLibrary(source)
end
end
+local function getLibInNode(source, nodeLib)
+ if not nodeLib then
+ return nil
+ end
+ if not nodeLib.child then
+ return nil
+ end
+ local key = guide.getKeyString(source)
+ local defLib = nodeLib.child[key]
+ return defLib
+end
+
+local function getNodeAsTable(source)
+ local node = source.node
+ local nodeGlobalName = vm.getGlobal(node)
+ if not nodeGlobalName then
+ return nil
+ end
+ local nodeName = nodeGlobalName:match '^s|(.+)$'
+ return getLibInNode(source, library.global[nodeName])
+end
+
+local function getNodeAsObject(source)
+ local node = source.node
+ local values = vm.getValue(node)
+ if not values then
+ return nil
+ end
+ for i = 1, #values do
+ local value = values[i]
+ local type = value.type
+ local nodeLib = library.object[type]
+ local lib = getLibInNode(source, nodeLib)
+ if lib then
+ return lib
+ end
+ end
+ return nil
+end
+
+local function checkNode(source)
+ if source.type ~= 'getfield'
+ and source.type ~= 'getmethod'
+ and source.type ~= 'getindex' then
+ return nil
+ end
+ return getNodeAsTable(source)
+ or getNodeAsObject(source)
+end
+
local function getLibrary(source)
local lib = checkStdLibrary(source)
if lib then
return lib
end
- return vm.eachRef(source, function (info)
- local src = info.source
- if src.type ~= 'getfield'
- and src.type ~= 'getmethod'
- and src.type ~= 'getindex' then
- return
- end
- local node = src.node
- local nodeGlobalName = vm.getGlobal(node)
- if not nodeGlobalName then
- return
- end
- local nodeName = nodeGlobalName:match '^s|(.+)$'
- local nodeLib = library.global[nodeName]
- if not nodeLib then
- return
- end
- if not nodeLib.child then
- return
- end
- local key = guide.getKeyString(src)
- local defLib = nodeLib.child[key]
- return defLib
+ return checkNode(source) or vm.eachRef(source, function (info)
+ return checkNode(info.source)
end)
end
diff --git a/server-beta/src/vm/getValue.lua b/server-beta/src/vm/getValue.lua
index 086bc6f5..88f01721 100644
--- a/server-beta/src/vm/getValue.lua
+++ b/server-beta/src/vm/getValue.lua
@@ -438,6 +438,9 @@ local function checkValue(source)
if source.value then
return vm.getValue(source.value)
end
+ if source.type == 'paren' then
+ return vm.getValue(source.exp)
+ end
end
local function checkCall(results, source)
@@ -484,11 +487,24 @@ local function checkDef(results, source)
end)
end
+local function checkLibrary(source)
+ local lib = vm.getLibrary(source)
+ if not lib then
+ return nil
+ end
+ return alloc {
+ type = lib.type,
+ value = lib.value,
+ source = vm.librarySource(lib),
+ }
+end
+
local function getValue(source)
local results = checkLiteral(source)
or checkValue(source)
or checkUnary(source)
or checkBinary(source)
+ or checkLibrary(source)
if results then
return results
end
@@ -539,23 +555,6 @@ function vm.checkTrue(source)
return current
end
---- 拥有某个类型的值
-function vm.eachValueType(source, type, callback)
- local values = vm.getValue(source)
- if not values then
- return
- end
- for i = 1, #values do
- local v = values[i]
- if v.type == type then
- local res = callback(v)
- if res ~= nil then
- return res
- end
- end
- end
-end
-
--- 获取特定类型的字面量值
function vm.getLiteral(source, type)
local values = vm.getValue(source)
@@ -603,6 +602,21 @@ function vm.isSameValue(a, b)
return true
end
+--- 是否包含某种类型
+function vm.hasType(source, type)
+ local values = vm.getValue(source)
+ if not values then
+ return false
+ end
+ for i = 1, #values do
+ local value = values[i]
+ if value.type == type then
+ return true
+ end
+ end
+ return false
+end
+
function vm.getType(source)
local values = vm.getValue(source)
if not values then
diff --git a/server-beta/src/vm/init.lua b/server-beta/src/vm/init.lua
index bf63db1d..4249de3d 100644
--- a/server-beta/src/vm/init.lua
+++ b/server-beta/src/vm/init.lua
@@ -7,4 +7,5 @@ require 'vm.getLinks'
require 'vm.getGlobal'
require 'vm.getLibrary'
require 'vm.getValue'
+require 'vm.dummySource'
return vm
diff --git a/server-beta/test/type_inference/init.lua b/server-beta/test/type_inference/init.lua
index 67faadf6..c81fc15d 100644
--- a/server-beta/test/type_inference/init.lua
+++ b/server-beta/test/type_inference/init.lua
@@ -150,6 +150,10 @@ TEST 'string' [[
]]
TEST 'function' [[
+<?x?> = ('x').sub
+]]
+
+TEST 'function' [[
<?x?> = _VERSION.sub
]]