diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-09-30 16:09:02 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-09-30 16:09:02 +0800 |
commit | 225e1aaeda6f956cc63f689df3a03b31e5804d44 (patch) | |
tree | 7cb6fc4e8d513217b0ff79672ea1e6a91cbe26b7 | |
parent | 212b100f3e49107eac588cb97e8fca46218b033b (diff) | |
download | lua-language-server-225e1aaeda6f956cc63f689df3a03b31e5804d44.zip |
换成搜索
-rw-r--r-- | server-beta/src/core/definition.lua | 16 | ||||
-rw-r--r-- | server-beta/src/core/engineer.lua | 62 | ||||
-rw-r--r-- | server-beta/src/parser/compile.lua | 118 | ||||
-rw-r--r-- | server-beta/src/parser/guide.lua | 82 |
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 |