From c025849321b444b84eacd4e091cfa574ca6bc472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 24 Sep 2019 21:41:04 +0800 Subject: =?UTF-8?q?=E6=9B=B4=E6=96=B0=20definition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-beta/src/core/definition.lua | 75 ++++++++++++++++++++++++++---------- server-beta/src/parser/guide.lua | 20 ++++++++++ server-beta/test/definition/init.lua | 8 +++- 3 files changed, 80 insertions(+), 23 deletions(-) (limited to 'server-beta') diff --git a/server-beta/src/core/definition.lua b/server-beta/src/core/definition.lua index da0e6d69..6f6689b4 100644 --- a/server-beta/src/core/definition.lua +++ b/server-beta/src/core/definition.lua @@ -2,40 +2,73 @@ local guide = require 'parser.guide' local m = {} -function m.asgetlocal(ast, source, callback) - local loc = ast.root[source.loc] - if not loc then +function m.search(state, ast, source) + if not source then + return + end + if state.cache[source] then + return + end + state.cache[source] = true + local f = m['as' .. source.type] + if not f then return end - return m.aslocal(ast, loc, callback) + f(state, ast, source) end -function m.assetlocal(ast, source, callback) +function m.asgetlocal(state, ast, source) local loc = ast.root[source.loc] - if not loc then - return + m.search(state, ast, loc) +end + +function m.assetlocal(state, ast, source) + local loc = ast.root[source.loc] + m.search(state, ast, loc) + state.callback(source, ast.uri) +end + +function m.aslocal(state, ast, source) + state.callback(source, ast.uri) + if source.ref then + for _, ref in ipairs(source.ref) do + m.search(state, ast, ast.root[ref]) + end end - return m.aslocal(ast, loc, callback) end -function m.aslocal(ast, source, callback) - callback(source, ast.uri) +function m.assetglobal(state, ast, source) + local name = source[1] + guide.eachSourceOf(ast.root, 'setglobal', function (src) + if src[1] == name then + state.callback(src, ast.uri) + end + end) +end + +function m.asgetglobal(state, ast, source) + local name = source[1] + guide.eachSourceOf(ast.root, 'setglobal', function (src) + if src[1] == name then + state.callback(src, ast.uri) + end + end) end return function (ast, text, offset) local results = {} - guide.eachSource(ast.root, offset, function (source) - local tp = source.type - local f = m['as' .. tp] - if f then - f(ast, source, function (target, uri) - results[#results+1] = { - uri = uri or ast.uri, - source = source, - target = target, - } - end) + local state = { + cache = {}, + callback = function (target, uri) + results[#results+1] = { + uri = uri or ast.uri, + source = source, + target = target, + } end + } + guide.eachSource(ast.root, offset, function (source) + m.search(state, ast, source) end) if #results == 0 then return nil diff --git a/server-beta/src/parser/guide.lua b/server-beta/src/parser/guide.lua index d3ae7100..bd7f9150 100644 --- a/server-beta/src/parser/guide.lua +++ b/server-beta/src/parser/guide.lua @@ -1,6 +1,7 @@ local error = error local utf8Len = utf8.len local utf8Offset = utf8.offset +local type = type _ENV = nil @@ -195,6 +196,25 @@ function m.eachSource(root, offset, callback) end end +--- 遍历所有某种类型的source +function m.eachSourceOf(root, types, callback) + if type(types) == 'string' then + types = {[types] = true} + elseif type(types) == 'table' then + for i = 1, #types do + types[types[i]] = true + end + else + return + end + for i = 1, #root do + local source = root[i] + if types[source.type] then + callback(source) + end + end +end + --- 获取偏移对应的坐标(row从0开始,col为光标位置) ---@param lines table ---@return integer {name = 'row'} diff --git a/server-beta/test/definition/init.lua b/server-beta/test/definition/init.lua index 5a80273c..b9e9ec2a 100644 --- a/server-beta/test/definition/init.lua +++ b/server-beta/test/definition/init.lua @@ -42,8 +42,12 @@ function TEST(script) local ast = parser:compile(new_script, 'lua', 'Lua 5.3') assert(ast) - local positions = core(ast, new_script, pos) - if positions then + local results = core(ast, new_script, pos) + if results then + local positions = {} + for i, result in ipairs(results) do + positions[i] = { result.target.start, result.target.finish } + end assert(founded(target, positions)) else assert(#target == 0) -- cgit v1.2.3