summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-09-29 16:21:58 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-09-29 16:21:58 +0800
commit41b4fe57bf46f5e67a8f41bde4ded038955e178d (patch)
treeadb96c0c9243a009de73fc37c2baeb440949e6fe
parent32772cbf3b5fc4e01cc47b8339bdbdf19b743711 (diff)
downloadlua-language-server-41b4fe57bf46f5e67a8f41bde4ded038955e178d.zip
暂存
-rw-r--r--server-beta/src/core/definition.lua7
-rw-r--r--server-beta/src/core/engineer.lua48
-rw-r--r--server-beta/src/parser/ast.lua17
-rw-r--r--server-beta/src/parser/compile.lua9
-rw-r--r--server-beta/src/parser/guide.lua27
5 files changed, 48 insertions, 60 deletions
diff --git a/server-beta/src/core/definition.lua b/server-beta/src/core/definition.lua
index efee48fb..2f4a2da3 100644
--- a/server-beta/src/core/definition.lua
+++ b/server-beta/src/core/definition.lua
@@ -4,12 +4,9 @@ local engineer = require 'core.engineer'
return function (ast, text, offset)
local results = {}
local searcher = engineer(ast)
- guide.eachSource(offset, function (source)
+ guide.eachSource(ast.ast, offset, function (source)
searcher:eachRef(source, function (src, mode)
- if src.start == 0 then
- return
- end
- if mode == 'local' or mode == 'set' then
+ if mode == 'set' or mode == 'local' then
results[#results+1] = {
uri = ast.uri,
source = source,
diff --git a/server-beta/src/core/engineer.lua b/server-beta/src/core/engineer.lua
index a61ef8fd..8afbeac2 100644
--- a/server-beta/src/core/engineer.lua
+++ b/server-beta/src/core/engineer.lua
@@ -12,60 +12,26 @@ local mt = {}
mt.__index = mt
mt.type = 'engineer'
---- 获取对象作为域时的名字
-function mt:getFieldName(obj)
- if obj.type == 'getglobal' or obj.type == 'setglobal' then
- return obj[1]
- end
- return nil
-end
-
--- 查找所有局部变量引用
function mt:eachRefAsLocal(obj, callback)
callback(obj, 'local')
if obj.ref then
for _, ref in ipairs(obj.ref) do
- local refObj = self.root[ref]
- if refObj.type == 'setlocal' then
- callback(self.root[ref], 'set')
- elseif refObj.type == 'getlocal' then
- callback(self.root[ref], 'get')
+ if ref.type == 'setlocal' then
+ callback(ref, 'set')
+ elseif ref.type == 'getlocal' then
+ callback(ref, 'get')
end
end
end
end
---- 查找所有全局变量引用
-function mt:eachRefAsGlobal(obj, callback)
- local version = config.config.runtime.version
- if version ~= 'Lua 5.1' and version ~= 'LuaJIT' then
- self:eachRefAsField(obj, callback)
- return
- end
-end
-
---- 查找所有域引用
-function mt:eachRefAsField(obj, callback)
- local nodeID = obj.node
- if not nodeID then
- return
- end
- local node = self.root[nodeID]
- local key = guide.getKeyName(obj)
- if not key then
- return
- end
- guide.eachField(self.value, node, key, function ()
- end)
-end
-
--- 查找所有引用
function mt:eachRef(obj, callback)
if obj.type == 'local' then
self:eachRefAsLocal(obj, callback)
elseif obj.type == 'getlocal' or obj.type == 'setlocal' then
- local loc = self.root[obj.loc]
- self:eachRefAsLocal(loc, callback)
+ self:eachRefAsLocal(obj.loc, callback)
elseif obj.type == 'setglobal' or obj.type == 'getglobal' then
self:eachRefAsGlobal(obj, callback)
end
@@ -76,8 +42,8 @@ return function (ast)
ast.vm = {}
end
local self = setmetatable({
- step = 0,
- root = ast.root,
+ step = 0,
+ ast = ast.ast,
}, mt)
return self
end
diff --git a/server-beta/src/parser/ast.lua b/server-beta/src/parser/ast.lua
index cacb0e13..8094cc73 100644
--- a/server-beta/src/parser/ast.lua
+++ b/server-beta/src/parser/ast.lua
@@ -124,6 +124,9 @@ local function createLocal(key, effect, value, attrs)
key.effect = effect
key.value = value
key.attrs = attrs
+ if value then
+ key.range = value.finish
+ end
return key
end
@@ -179,7 +182,8 @@ local function packList(start, list, finish)
for i = count + 1, #list do
list[i] = nil
end
- list.start = start
+ list.type = 'list'
+ list.start = start
list.finish = finish - 1
return list
end
@@ -995,6 +999,9 @@ local Defs = {
key.type = 'setindex'
key.value = getValue(values, i)
end
+ if key.value then
+ key.range = key.value.finish
+ end
end
return tableUnpack(keys)
end,
@@ -1177,20 +1184,22 @@ local Defs = {
block.type = 'in'
block.start = start
block.finish = finish - 1
- block.keys = {}
+ block.keys = keys
local values
if func then
local call = createCall(exp, func.finish + 1, exp.finish)
call.node = func
+ call.start = func.start
values = { call }
+ keys.range = call.finish
end
for i = 1, #keys do
local loc = keys[i]
if values then
- block.keys[i] = createLocal(loc, blockStart, getValue(values, i))
+ createLocal(loc, blockStart, getValue(values, i))
else
- block.keys[i] = createLocal(loc, blockStart)
+ createLocal(loc, blockStart)
end
end
checkMissEnd(start)
diff --git a/server-beta/src/parser/compile.lua b/server-beta/src/parser/compile.lua
index 03632c03..90b3f269 100644
--- a/server-beta/src/parser/compile.lua
+++ b/server-beta/src/parser/compile.lua
@@ -3,7 +3,7 @@ local type = type
_ENV = nil
-local pushError, Compile, CompileBlock, Cache, Block, GoToTag, Version, ENVMode
+local pushError, Compile, CompileBlock, Cache, Block, GoToTag, Version, ENVMode, Compiled
--[[
-- value 类右字面量创建,在set get call中传递
@@ -416,6 +416,10 @@ function Compile(obj, parent)
if not obj then
return nil
end
+ if Compiled[obj] then
+ return
+ end
+ Compiled[obj] = true
local f = vmMap[obj.type]
if not f then
return
@@ -510,11 +514,14 @@ return function (self, lua, mode, version)
ENVMode = '_ENV'
end
Cache = {}
+ Compiled = {}
GoToTag = {}
if type(state.ast) == 'table' then
Compile(state.ast)
end
PostCompile()
Cache = nil
+ Compiled = nil
+ GoToTag = nil
return state
end
diff --git a/server-beta/src/parser/guide.lua b/server-beta/src/parser/guide.lua
index 095a975e..da851138 100644
--- a/server-beta/src/parser/guide.lua
+++ b/server-beta/src/parser/guide.lua
@@ -26,26 +26,35 @@ local breakBlockTypes = {
}
m.childMap = {
+ ['main'] = {'#'},
['repeat'] = {'#', 'filter'},
['while'] = {'filter', '#'},
['in'] = {'keys', '#'},
['loop'] = {'loc', 'max', 'step', '#'},
+ ['if'] = {'#'},
['ifblock'] = {'filter', '#'},
['elseifblock'] = {'filter', '#'},
+ ['elseblock'] = {'#'},
['setfield'] = {'node', 'value'},
['local'] = {'attrs', 'value'},
['setlocal'] = {'value'},
+ ['return'] = {'#'},
+ ['do'] = {'#'},
['index'] = {'index'},
+ ['table'] = {'#'},
['tableindex'] = {'index', 'value'},
['tablefield'] = {'value'},
['function'] = {'args'},
+ ['funcargs'] = {'#'},
['setmethod'] = {'node', 'method', 'value'},
['getmethod'] = {'node', 'method'},
['setindex'] = {'node', 'index', 'value'},
['getindex'] = {'node', 'index'},
['paren'] = {'exp'},
['call'] = {'node', 'args'},
+ ['callargs'] = {'#'},
['getfield'] = {'node'},
+ ['list'] = {'#'},
}
--- 寻找所在函数
@@ -196,12 +205,14 @@ end
--- 判断source是否包含offset
function m.isContain(source, offset)
- if not source.start then
- return false
- end
return source.start <= offset and source.finish >= offset - 1
end
+--- 判断offset在source的范围内
+function m.isInRange(source, offset)
+ return source.start <= offset and (source.range or source.finish) >= offset - 1
+end
+
--- 遍历所有包含offset的source
function m.eachSource(ast, offset, callback)
local map = m.childMap
@@ -213,8 +224,10 @@ function m.eachSource(ast, offset, callback)
end
local obj = list[len]
list[len] = nil
- if m.isContain(obj, offset) then
- callback(obj)
+ if m.isInRange(obj, offset) then
+ if m.isContain(obj, offset) then
+ callback(obj)
+ end
local keys = map[obj.type]
if keys then
for i = 1, #keys do
@@ -227,10 +240,6 @@ function m.eachSource(ast, offset, callback)
list[#list+1] = obj[key]
end
end
- else
- for i = 1, #obj do
- list[#list+1] = obj[i]
- end
end
end
end