diff options
Diffstat (limited to 'server/src/core')
-rw-r--r-- | server/src/core/definition.lua | 10 | ||||
-rw-r--r-- | server/src/core/implementation.lua | 119 |
2 files changed, 105 insertions, 24 deletions
diff --git a/server/src/core/definition.lua b/server/src/core/definition.lua index 9b9cd75e..35dfc03b 100644 --- a/server/src/core/definition.lua +++ b/server/src/core/definition.lua @@ -6,14 +6,20 @@ local function parseValueSimily(vm, source, lsp) local positions = {} for _, other in ipairs(vm.sources) do if other == source then - break + goto CONTINUE end - if other[1] == key and not other:bindLocal() and other:bindValue() and other:action() == 'set' then + if other[1] == key + and not other:bindLocal() + and other:bindValue() + and other:action() == 'set' + and source:bindValue() ~= other:bindValue() + then positions[#positions+1] = { other.start, other.finish, } end + :: CONTINUE :: end if #positions == 0 then return nil diff --git a/server/src/core/implementation.lua b/server/src/core/implementation.lua index 1d36bd4d..b7ca2c6e 100644 --- a/server/src/core/implementation.lua +++ b/server/src/core/implementation.lua @@ -1,48 +1,111 @@ -local function parseLocal(vm, loc, lsp) +local function parseValueSimily(vm, source, lsp) + local key = source[1] + if not key then + return nil + end local positions = {} - positions[#positions+1] = { - loc.source.start, - loc.source.finish, - } + for _, other in ipairs(vm.sources) do + if other == source then + goto CONTINUE + end + if other[1] == key + and not other:bindLocal() + and other:bindValue() + and other:action() == 'set' + and source:bindValue() ~= other:bindValue() + then + positions[#positions+1] = { + other.start, + other.finish, + } + end + :: CONTINUE :: + end if #positions == 0 then return nil end return positions end -local function parseValue(vm, value, lsp) +local function parseValueCrossFile(vm, source, lsp) + local value = source:bindValue() local positions = {} value:eachInfo(function (info) - if info.type == 'set' then + if info.type == 'local' and info.source.uri == value.uri then positions[#positions+1] = { info.source.start, info.source.finish, + value.uri, } + return true end end) - if #positions == 0 then - return nil + if #positions > 0 then + return positions + end + + value:eachInfo(function (info) + if info.type == 'set' and info.source.uri == value.uri then + positions[#positions+1] = { + info.source.start, + info.source.finish, + value.uri, + } + end + end) + if #positions > 0 then + return positions + end + + value:eachInfo(function (info) + if info.type == 'return' and info.source.uri == value.uri then + positions[#positions+1] = { + info.source.start, + info.source.finish, + value.uri, + } + end + end) + if #positions > 0 then + return positions + end + + local destVM = lsp:getVM(value.uri) + if not destVM then + positions[#positions+1] = { + 0, 0, value.uri, + } + return positions + end + + local result = parseValueSimily(destVM, source, lsp) + if result then + for _, position in ipairs(result) do + positions[#positions+1] = position + position[3] = value.uri + end end + if #positions > 0 then + return positions + end + return positions end -local function parseValueSimily(vm, source, lsp) - local key = source[1] - if not key then - return nil +local function parseValue(vm, source, lsp) + local value = source:bindValue() + if value.uri ~= vm.uri then + return parseValueCrossFile(vm, source, lsp) end local positions = {} - for _, other in ipairs(vm.sources) do - if other == source then - break - end - if other[1] == key and not other:bindLocal() and other:bindValue() and other:action() == 'set' then + value:eachInfo(function (info) + if info.type == 'set' then positions[#positions+1] = { - other.start, - other.finish, + info.source.start, + info.source.finish, } end - end + end) if #positions == 0 then return nil end @@ -65,15 +128,27 @@ local function parseLabel(vm, label, lsp) return positions end +local function jumpUri(vm, source, lsp) + local uri = source:get 'target uri' + local positions = {} + positions[#positions+1] = { + 0, 0, uri, + } + return positions +end + return function (vm, source, lsp) if not source then return nil end if source:bindValue() then - return parseValue(vm, source:bindValue(), lsp) + return parseValue(vm, source, lsp) or parseValueSimily(vm, source, lsp) end if source:bindLabel() then return parseLabel(vm, source:bindLabel(), lsp) end + if source:get 'target uri' then + return jumpUri(vm, source, lsp) + end end |