summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-09-30 16:09:02 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-09-30 16:09:02 +0800
commit225e1aaeda6f956cc63f689df3a03b31e5804d44 (patch)
tree7cb6fc4e8d513217b0ff79672ea1e6a91cbe26b7
parent212b100f3e49107eac588cb97e8fca46218b033b (diff)
downloadlua-language-server-225e1aaeda6f956cc63f689df3a03b31e5804d44.zip
换成搜索
-rw-r--r--server-beta/src/core/definition.lua16
-rw-r--r--server-beta/src/core/engineer.lua62
-rw-r--r--server-beta/src/parser/compile.lua118
-rw-r--r--server-beta/src/parser/guide.lua82
4 files changed, 51 insertions, 227 deletions
diff --git a/server-beta/src/core/definition.lua b/server-beta/src/core/definition.lua
index 2f4a2da3..bd8124d2 100644
--- a/server-beta/src/core/definition.lua
+++ b/server-beta/src/core/definition.lua
@@ -3,16 +3,14 @@ local engineer = require 'core.engineer'
return function (ast, text, offset)
local results = {}
- local searcher = engineer(ast)
guide.eachSource(ast.ast, offset, function (source)
- searcher:eachRef(source, function (src, mode)
- if mode == 'set' or mode == 'local' then
- results[#results+1] = {
- uri = ast.uri,
- source = source,
- target = src,
- }
- end
+ local searcher = engineer(ast)
+ searcher:eachRef(source, 'def', function (src, mode)
+ results[#results+1] = {
+ uri = ast.uri,
+ source = source,
+ target = src,
+ }
end)
end)
if #results == 0 then
diff --git a/server-beta/src/core/engineer.lua b/server-beta/src/core/engineer.lua
index a9251996..74c6ca33 100644
--- a/server-beta/src/core/engineer.lua
+++ b/server-beta/src/core/engineer.lua
@@ -12,41 +12,49 @@ local mt = {}
mt.__index = mt
mt.type = 'engineer'
---- 查找所有局部变量引用
-function mt:eachRefAsLocal(obj, callback)
- callback(obj, 'local')
- if obj.ref then
- for _, ref in ipairs(obj.ref) do
- if ref.type == 'setlocal' then
- callback(ref, 'set')
- elseif ref.type == 'getlocal' then
- callback(ref, 'get')
+mt['local'] = function (self, source, mode, callback)
+ if mode == 'def' then
+ callback(source, 'local')
+ if source.ref then
+ for _, ref in ipairs(source.ref) do
+ if ref.type == 'setlocal' then
+ callback(ref, 'set')
+ end
end
end
end
end
-
---- 查找所有域的引用
-function mt:eachRefAsField(obj, callback)
- local node = obj.node
- guide.eachChildRef(node, function (ref)
- if ref.type == 'setglobal' or ref.type == 'setfield' then
- callback(ref, 'set')
- elseif ref.type == 'getglobal' or ref.type == 'getfield' then
- callback(ref, 'get')
+mt['getlocal'] = function (self, source, mode, callback)
+ self:search(source.loc, 'local', mode, callback)
+end
+mt['setlocal'] = mt['getlocal']
+mt['_ENV'] = function (self, source, mode, callback)
+ if mode == 'def' then
+ if source.ref then
+ for _, ref in ipairs(source.ref) do
+ if ref.type == 'setglobal' then
+ callback(ref, 'set')
+ end
+ end
end
- end)
+ end
end
+mt['getglobal'] = function (self, source, mode, callback)
+ self:search(source.node, '_ENV', mode, callback)
+end
+mt['setglobal'] = mt['getglobal']
---- 查找所有引用
-function mt:eachRef(obj, callback)
- if obj.type == 'local' then
- self:eachRefAsLocal(obj, callback)
- elseif obj.type == 'getlocal' or obj.type == 'setlocal' then
- self:eachRefAsLocal(obj.loc, callback)
- elseif obj.type == 'setglobal' or obj.type == 'getglobal' then
- self:eachRefAsField(obj, callback)
+function mt:search(source, method, mode, callback)
+ local f = mt[method]
+ if not f then
+ return
end
+ f(self, source, mode, callback)
+end
+
+function mt:eachRef(source, mode, callback)
+ local tp = source.type
+ self:search(source, tp, mode, callback)
end
return function (ast)
diff --git a/server-beta/src/parser/compile.lua b/server-beta/src/parser/compile.lua
index fe4198f0..95829130 100644
--- a/server-beta/src/parser/compile.lua
+++ b/server-beta/src/parser/compile.lua
@@ -3,98 +3,9 @@ local type = type
_ENV = nil
-local pushError, Compile, CompileBlock, Cache, Block, GoToTag, Version, ENVMode, Compiled
+local pushError, Compile, CompileBlock, Cache, Block, GoToTag, Version, ENVMode, Compiled, ValueID
---[[
--- value 类右字面量创建,在set get call中传递
--- obj 用 vref 表标记当前可能的 value 是哪些
-Value
- type -> 确定类型
- literal -> 字面量对象
- tag -> 特殊标记
- ref -> 值的引用者
- child -> 值的child
- func -> 函数对象
---]]
-
-local function addValue(obj, value)
- local vref = obj.vref
- if not vref then
- vref = {}
- obj.vref = vref
- Cache[vref] = {}
- end
- local cache = Cache[vref]
- if cache[value] then
- return
- end
- cache[value] = true
- vref[#vref+1] = value
- local valueRef = value.ref
- if not valueRef then
- valueRef = {}
- value.ref = valueRef
- end
- valueRef[#valueRef+1] = obj
-end
-
-local function getValue(obj)
- local vref = obj.vref
- if vref then
- return vref
- end
- if guide.isLiteral(obj) then
- addValue(obj, obj)
- else
- addValue(obj, {})
- end
- return obj.vref
-end
-
-local function mergeValue(obj1, obj2)
- local vref1 = obj1.vref
- local vref2 = obj2.vref
- if not vref2 then
- return
- end
- if not vref1 then
- vref1 = {}
- obj1.vref = vref1
- Cache[vref1] = {}
- end
- local cache = Cache[vref1]
- for i = 1, #vref2 do
- local value = vref2[i]
- if not cache[value] then
- cache[value] = true
- vref1[#vref1+1] = value
- local valueRef = value.ref
- if not valueRef then
- valueRef = {}
- value.ref = valueRef
- end
- valueRef[#valueRef+1] = obj1
- end
- end
-end
-
-local function setChildValue(obj, key, value)
- if not value then
- return
- end
- local objVref = getValue(obj)
- local keyName = guide.getKeyName(key)
- local valueVref = getValue(value)
- for i = 1, #objVref do
- local v = objVref[i]
- if not v.child then
- v.child = {}
- end
- v.child[keyName] = valueVref
- end
-end
-
-local function addLocalRef(node, obj)
+local function addRef(node, obj)
if not node.ref then
node.ref = {}
end
@@ -108,16 +19,13 @@ local vmMap = {
if loc then
obj.type = 'getlocal'
obj.loc = loc
- if not loc.ref then
- loc.ref = {}
- end
- loc.ref[#loc.ref+1] = obj
+ addRef(loc, obj)
else
obj.type = 'getglobal'
if ENVMode == '_ENV' then
local node = guide.getLocal(obj, '_ENV', obj.start)
if node then
- addLocalRef(node, obj)
+ addRef(node, obj)
end
end
end
@@ -235,17 +143,13 @@ local vmMap = {
if loc then
obj.type = 'setlocal'
obj.loc = loc
- if not loc.ref then
- loc.ref = {}
- end
- loc.ref[#loc.ref+1] = obj
+ addRef(loc, obj)
else
obj.type = 'setglobal'
if ENVMode == '_ENV' then
local node = guide.getLocal(obj, '_ENV', obj.start)
if node then
- addLocalRef(node, obj)
- setChildValue(node, obj, obj.value)
+ addRef(node, obj)
end
end
end
@@ -387,18 +291,13 @@ local vmMap = {
['main'] = function (obj)
Block = obj
if ENVMode == '_ENV' then
- local env = {
+ Compile({
type = 'local',
start = 0,
finish = 0,
effect = 0,
[1] = '_ENV',
- }
- Compile(env, obj)
- addValue(env, {
- type = 'table',
- tag = '_ENV',
- })
+ }, obj)
end
CompileBlock(obj, obj)
Block = nil
@@ -520,6 +419,7 @@ return function (self, lua, mode, version)
Cache = {}
Compiled = {}
GoToTag = {}
+ ValueID = 0
if type(state.ast) == 'table' then
Compile(state.ast)
end
diff --git a/server-beta/src/parser/guide.lua b/server-beta/src/parser/guide.lua
index f89b1f5f..3fb34d51 100644
--- a/server-beta/src/parser/guide.lua
+++ b/server-beta/src/parser/guide.lua
@@ -349,86 +349,4 @@ function m.lineRange(lines, row)
return line.start + 1, line.finish
end
---- 获取对象作为key时的名字
-function m.getKeyName(obj)
- if obj.type == 'getglobal' or obj.type == 'setglobal' then
- return 's|' .. obj[1]
- elseif obj.type == 'getfield' or obj.type == 'getglobal' then
- return 's|' .. obj[1]
- end
-end
-
---- 获取对象所有field的key与valueObj
-function m.eachChildValue(obj, callback)
- local vref = obj.vref
- if not vref then
- return
- end
- for i = 1, #vref do
- local v = vref[i]
- local child = v.child
- if child then
- for fieldName, cvref in next, child do
- for j = 1, #cvref do
- callback(fieldName, cvref[j])
- end
- end
- end
- end
-end
-
---- 获取对象所有指定field的key与valueObj
-function m.eachChildValueOf(obj, field, callback)
- local vref = obj.vref
- if not vref then
- return
- end
- for i = 1, #vref do
- local v = vref[i]
- local child = v.child
- if child then
- local cvref = child[field]
- if cvref then
- for j = 1, #cvref do
- callback(cvref[j])
- end
- end
- end
- end
-end
-
---- 获取对象所有field的引用
-function m.eachChildRef(obj, callback)
- local vref = obj.vref
- if not vref then
- return
- end
- for x = 1, #vref do
- local v = vref[x]
- local cref = v.ref
- if cref then
- for y = 1, #cref do
- local co = cref[y]
- local ref = co.ref
- if ref then
- for i = 1, #ref do
- callback(ref[i])
- end
- end
- end
- end
- end
-end
-
---- 获取对象的所有引用
-function m.eachRef(obj, callback)
- local ref = obj.ref
- if not ref then
- return
- end
- for i = 1, #ref do
- callback(ref[i])
- end
-end
-
return m