summaryrefslogtreecommitdiff
path: root/server-beta/src/searcher/eachRef.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server-beta/src/searcher/eachRef.lua')
-rw-r--r--server-beta/src/searcher/eachRef.lua104
1 files changed, 77 insertions, 27 deletions
diff --git a/server-beta/src/searcher/eachRef.lua b/server-beta/src/searcher/eachRef.lua
index 94419c18..63720ec9 100644
--- a/server-beta/src/searcher/eachRef.lua
+++ b/server-beta/src/searcher/eachRef.lua
@@ -1,11 +1,23 @@
local guide = require 'parser.guide'
+local function ofSelf(searcher, loc, callback)
+ -- self 的2个特殊引用位置:
+ -- 1. 当前方法定义时的对象(mt)
+ local method = loc.method
+ local node = method.node
+ searcher:eachRef(node, callback)
+ -- 2. 调用该方法时传入的对象
+end
+
local function ofLocal(searcher, loc, callback)
- callback {
- searcher = searcher,
- source = loc,
- mode = 'declare',
- }
+ -- 方法中的 self 使用了一个虚拟的定义位置
+ if loc.tag ~= 'self' then
+ callback {
+ searcher = searcher,
+ source = loc,
+ mode = 'declare',
+ }
+ end
if loc.ref then
for _, ref in ipairs(loc.ref) do
if ref.type == 'getlocal' then
@@ -23,39 +35,77 @@ local function ofLocal(searcher, loc, callback)
end
end
end
+ if loc.tag == 'self' then
+ ofSelf(searcher, loc, callback)
+ end
+end
+
+local function checkField(key, info, callback)
+ local src = info.source
+ if key ~= guide.getKeyName(src) then
+ return
+ end
+ local mode
+ if src.type == 'setglobal' then
+ mode = 'set'
+ elseif src.type == 'getglobal' then
+ mode = 'get'
+ elseif src.type == 'field' then
+ local parent = src.parent
+ if parent.type == 'setfield' then
+ mode = 'set'
+ elseif parent.type == 'getfield' then
+ mode = 'get'
+ elseif parent.type == 'tablefield' then
+ mode = 'set'
+ end
+ elseif src.type == 'method' then
+ local parent = src.parent
+ if parent.type == 'setmethod' then
+ mode = 'set'
+ elseif parent.type == 'getmethod' then
+ mode = 'get'
+ end
+ end
+ if mode then
+ callback {
+ searcher = info.searcher,
+ source = src,
+ mode = mode,
+ }
+ end
end
local function ofGlobal(searcher, source, callback)
local node = source.node
local key = guide.getKeyName(source)
- searcher.node:eachField(node, function (info)
- local src = info.source
- if key == guide.getKeyName(src) then
- if src.type == 'setglobal' then
- callback {
- searcher = searcher,
- source = src,
- mode = 'set',
- }
- elseif src.type == 'getglobal' then
- callback {
- searcher = searcher,
- source = src,
- mode = 'get',
- }
- end
- end
+ searcher:eachField(node, function (info)
+ checkField(key, info, callback)
+ end)
+end
+
+local function ofField(searcher, source, callback)
+ local parent = source.parent
+ local node = parent.node
+ local key = guide.getKeyName(source)
+ searcher:eachField(node, function (info)
+ checkField(key, info, callback)
end)
end
return function (searcher, source, callback)
- if source.type == 'local' then
+ local stype = source.type
+ if stype == 'local' then
ofLocal(searcher, source, callback)
- elseif source.type == 'getlocal'
- or source.type == 'setlocal' then
+ elseif stype == 'getlocal'
+ or stype == 'setlocal' then
ofLocal(searcher, source.node, callback)
- elseif source.type == 'setglobal'
- or source.type == 'getglobal' then
+ elseif stype == 'setglobal'
+ or stype == 'getglobal' then
ofGlobal(searcher, source, callback)
+ elseif stype == 'field'
+ or stype == 'method'
+ or stype == 'index' then
+ ofField(searcher, source, callback)
end
end