From 6478e7db3913c4ab76a5a2735569d33a7dc7ca62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 24 Oct 2019 17:02:40 +0800 Subject: local --- server-beta/src/core/definition.lua | 35 ++++++++++--------- server-beta/src/searcher/eachRef.lua | 33 ++++++++++++++++++ server-beta/src/searcher/getField.lua | 3 ++ server-beta/src/searcher/getValue.lua | 2 +- server-beta/src/searcher/init.lua | 65 +++++++++++++++++++++++++---------- 5 files changed, 102 insertions(+), 36 deletions(-) create mode 100644 server-beta/src/searcher/eachRef.lua create mode 100644 server-beta/src/searcher/getField.lua (limited to 'server-beta') diff --git a/server-beta/src/core/definition.lua b/server-beta/src/core/definition.lua index 91d8f499..305bb868 100644 --- a/server-beta/src/core/definition.lua +++ b/server-beta/src/core/definition.lua @@ -3,22 +3,25 @@ local workspace = require 'workspace' local files = require 'files' local function findDef(searcher, source, callback) - searcher:eachDef(source, function (info) - local src = info.source - local uri = info.uri - if src.type == 'setfield' - or src.type == 'getfield' - or src.type == 'tablefield' then - callback(src.field, uri) - elseif src.type == 'setindex' - or src.type == 'getindex' - or src.type == 'tableindex' then - callback(src.index, uri) - elseif src.type == 'getmethod' - or src.type == 'setmethod' then - callback(src.method, uri) - else - callback(src, uri) + searcher:eachRef(source, function (info) + if info.mode == 'declare' + or info.mode == 'set' then + local src = info.source + local uri = info.uri + if src.type == 'setfield' + or src.type == 'getfield' + or src.type == 'tablefield' then + callback(src.field, uri) + elseif src.type == 'setindex' + or src.type == 'getindex' + or src.type == 'tableindex' then + callback(src.index, uri) + elseif src.type == 'getmethod' + or src.type == 'setmethod' then + callback(src.method, uri) + else + callback(src, uri) + end end end) end diff --git a/server-beta/src/searcher/eachRef.lua b/server-beta/src/searcher/eachRef.lua new file mode 100644 index 00000000..47cb8f27 --- /dev/null +++ b/server-beta/src/searcher/eachRef.lua @@ -0,0 +1,33 @@ +local function ofLocal(searcher, loc, callback) + callback { + searcher = searcher, + source = loc, + mode = 'declare', + } + if loc.ref then + for _, ref in ipairs(loc.ref) do + if ref.type == 'getlocal' then + callback { + searcher = searcher, + source = ref, + mode = 'get', + } + elseif ref.type == 'setlocal' then + callback { + searcher = searcher, + source = ref, + mode = 'set', + } + end + end + end +end + +return function (searcher, source, callback) + if source.type == 'local' then + ofLocal(searcher, source, callback) + elseif source.type == 'getlocal' + or source.type == 'setlocal' then + ofLocal(searcher, source.node, callback) + end +end diff --git a/server-beta/src/searcher/getField.lua b/server-beta/src/searcher/getField.lua new file mode 100644 index 00000000..0957a029 --- /dev/null +++ b/server-beta/src/searcher/getField.lua @@ -0,0 +1,3 @@ +return function (searcher, source) + +end diff --git a/server-beta/src/searcher/getValue.lua b/server-beta/src/searcher/getValue.lua index 5f716b65..70e10bef 100644 --- a/server-beta/src/searcher/getValue.lua +++ b/server-beta/src/searcher/getValue.lua @@ -1,2 +1,2 @@ -return function () +return function (searcher, source) end diff --git a/server-beta/src/searcher/init.lua b/server-beta/src/searcher/init.lua index 5a6bc014..b146ed82 100644 --- a/server-beta/src/searcher/init.lua +++ b/server-beta/src/searcher/init.lua @@ -1,6 +1,9 @@ local guide = require 'parser.guide' local files = require 'files' +local util = require 'utility' local getValue = require 'searcher.getValue' +local getField = require 'searcher.getField' +local eachRef = require 'searcher.eachRef' local setmetatable = setmetatable local assert = assert @@ -21,29 +24,56 @@ local specials = { local mt = {} mt.__index = mt mt.__name = 'searcher' -mt._step = 0 -function mt:step() - self._step = self._step + 1 - assert(self.step <= 100, 'Stack overflow!') - if not self._stepClose then - self._stepClose = setmetatable({}, { - __close = function () - self._step = self._step - 1 - end - }) +function mt:lock(tp, source) + if self.locked[tp][source] then + return nil end - return self._stepClose + self.locked[tp][source] = true + return util.defer(function () + self.locked[tp][source] = nil + end) end --- 获取关联的值 ---@param source table ---@return value table function mt:getValue(source) - local _ = self:step() + local lock = self:lock('getValue', source) + if not lock then + return nil + end return getValue(self, source) end +--- 获取关联的field +---@param source table +---@return table field +function mt:getField(source) + return getField(self, source) +end + +--- 获取所有的定义(不递归) +function mt:eachRef(source, callback) + local lock = self:lock('eachRef', source) + if not lock then + return + end + local cache = self.cache.eachRef[source] + if cache then + for i = 1, #cache do + callback(cache[i]) + end + return + end + cache = {} + self.cache.eachRef[source] = cache + eachRef(self, source, function (info) + cache[#cache+1] = info + callback(info) + end) +end + ---@class engineer local m = {} @@ -56,14 +86,11 @@ function m.create(uri) ast = ast.ast, uri = uri, cache = { - def = {}, - ref = {}, - field = {}, - value = {}, - specialName = {}, + eachRef = {}, }, - lock = { - value = {}, + locked = { + getValue = {}, + eachRef = {}, } }, mt) return searcher -- cgit v1.2.3