diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/core/definition.lua | 77 | ||||
-rw-r--r-- | server/src/vm/value.lua | 56 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 6 |
3 files changed, 83 insertions, 56 deletions
diff --git a/server/src/core/definition.lua b/server/src/core/definition.lua index 6d5fe93e..2b476b92 100644 --- a/server/src/core/definition.lua +++ b/server/src/core/definition.lua @@ -1,4 +1,28 @@ -local function parseValueCrossFile(vm, value, lsp) +local function parseValueSimily(vm, source, lsp) + local key = source[1] + if not key then + return nil + 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 + positions[#positions+1] = { + other.start, + other.finish, + } + end + end + if #positions == 0 then + return nil + end + return positions +end + +local function parseValueCrossFile(vm, source, lsp) + local value = source:bindValue() local positions = {} value:eachInfo(function (info) if info.type == 'local' and info.source.uri == value.uri then @@ -32,6 +56,18 @@ local function parseValueCrossFile(vm, value, lsp) } 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 + local main = destVM.main local mainValue = main:getFunction() local mainSource = mainValue.source @@ -46,10 +82,11 @@ local function parseValueCrossFile(vm, value, lsp) return positions end -local function parseLocal(vm, loc, lsp) - local value = loc:getValue() +local function parseLocal(vm, source, lsp) + local loc = source:bindLocal() + local value = source:bindValue() if value.uri ~= vm.uri then - return parseValueCrossFile(vm, value, lsp) + return parseValueCrossFile(vm, source, lsp) end local positions = {} positions[#positions+1] = { @@ -62,9 +99,10 @@ local function parseLocal(vm, loc, lsp) return positions end -local function parseValue(vm, value, lsp) +local function parseValue(vm, source, lsp) + local value = source:bindValue() if value.uri ~= vm.uri then - return parseValueCrossFile(vm, value, lsp) + return parseValueCrossFile(vm, source, lsp) end local positions = {} value:eachInfo(function (info) @@ -81,29 +119,6 @@ local function parseValue(vm, value, lsp) return positions end -local function parseValueSimily(vm, source, lsp) - local key = source[1] - if not key then - return nil - 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 - positions[#positions+1] = { - other.start, - other.finish, - } - end - end - if #positions == 0 then - return nil - end - return positions -end - local function parseLabel(vm, label, lsp) local positions = {} label:eachInfo(function (info) @@ -134,10 +149,10 @@ return function (vm, source, lsp) return nil end if source:bindLocal() then - return parseLocal(vm, source:bindLocal(), lsp) + return parseLocal(vm, source, lsp) 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 diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index 39a6f1aa..695734e7 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -14,6 +14,25 @@ mt.__index = mt mt.type = 'value' mt.uri = '' +local function create (tp, source, literal) + if tp == '...' then + error('Value type cant be ...') + end + local self = setmetatable({ + source = source or getDefaultSource(), + _type = {}, + _literal = literal, + }, mt) + if type(tp) == 'table' then + for i = 1, #tp do + self:setType(tp[i], 1.0 / #tp) + end + else + self:setType(tp, 1.0) + end + return self +end + function mt:setType(tp, rate) if type(tp) == 'table' then for _, ctp in ipairs(tp) do @@ -93,7 +112,7 @@ function mt:eachLibChild(callback) end end -function mt:getChild(index, mark) +function mt:getChild(index, source, mark) self:setType('table', 0.5) local value = self:rawGet(index) if value then @@ -101,16 +120,26 @@ function mt:getChild(index, mark) end local method = self:getMetaMethod('__index') if not method then - return self:getLibChild(index) + local v = self:getLibChild(index) + if v then + return v + end + v = create('any', source) + self:setChild(index, v) + v.uri = self.uri + return v end if not mark then mark = {} end if mark[method] then - return nil + local v = create('any', source) + self:setChild(index, v) + v.uri = self.uri + return v end mark[method] = true - return method:getChild(index, mark) + return method:getChild(index, source, mark) end function mt:setMetaTable(metatable) @@ -248,21 +277,4 @@ function mt:getLiteral() return self._literal end -return function (tp, source, literal) - if tp == '...' then - error('Value type cant be ...') - end - local self = setmetatable({ - source = source or getDefaultSource(), - _type = {}, - _literal = literal, - }, mt) - if type(tp) == 'table' then - for i = 1, #tp do - self:setType(tp[i], 1.0 / #tp) - end - else - self:setType(tp, 1.0) - end - return self -end +return create diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua index 4ff5f372..643c68ea 100644 --- a/server/src/vm/vm.lua +++ b/server/src/vm/vm.lua @@ -349,7 +349,7 @@ function mt:getName(name, source) end local ENV = self:loadLocal('_ENV') local ENVValue = ENV:getValue() - global = ENVValue:getChild(name) or ENVValue:setChild(name, createValue('any', source)) + global = ENVValue:getChild(name, source) source:bindValue(global, 'get') source:set('global', true) source:set('parent', ENVValue) @@ -477,12 +477,12 @@ function mt:getSimple(simple, max) source:set('parent', value) local child = source[1] local index = self:getIndex(child) - value = value:getChild(index) or value:setChild(index, createValue('any', source)) + value = value:getChild(index, source) source:bindValue(value, 'get') elseif source.type == 'name' then source:set('parent', value) source:set('object', object) - value = value:getChild(source[1]) or value:setChild(source[1], createValue('any', source)) + value = value:getChild(source[1], source) source:bindValue(value, 'get') elseif source.type == ':' then object = value |