diff options
Diffstat (limited to 'server/src/core')
-rw-r--r-- | server/src/core/completion.lua | 83 | ||||
-rw-r--r-- | server/src/core/definition.lua | 205 | ||||
-rw-r--r-- | server/src/core/diagnostics.lua | 27 | ||||
-rw-r--r-- | server/src/core/implementation.lua | 21 |
4 files changed, 178 insertions, 158 deletions
diff --git a/server/src/core/completion.lua b/server/src/core/completion.lua index 4a487441..d0da95cd 100644 --- a/server/src/core/completion.lua +++ b/server/src/core/completion.lua @@ -397,6 +397,14 @@ local function searchEmmyKeyword(vm, source, word, callback) end end +local function searchEmmyClass(vm, source, word, callback) + vm.emmyMgr:eachClass(function (class) + if matchKey(word, class:getName()) then + callback(class:getName(), class:getSource(), CompletionItemKind.Class) + end + end) +end + local function searchSource(vm, source, word, callback) if source.type == 'keyword' then searchAsKeyowrd(vm, source, word, callback) @@ -430,6 +438,9 @@ local function searchSource(vm, source, word, callback) searchEmmyKeyword(vm, source, word, callback) return end + if source:get 'target class' then + searchEmmyClass(vm, source, word, callback) + end end local function searchInRequire(vm, select, source, callback) @@ -650,11 +661,9 @@ local function makeList(source, pos, word) end, list end -local function searchToclose(text, word, callback, pos) - if #word > 0 then - pos = pos - 1 - end - if text:sub(pos, pos) ~= '*' then +local function searchToclose(text, source, word, callback) + local pos = source.start + if text:sub(pos-1, pos-1) ~= '*' then return false end if not matchKey(word, 'toclose') then @@ -685,7 +694,62 @@ local function keywordSource(vm, word, pos) } end -return function (vm, text, pos, word, oldText) +local function findStartPos(pos, buf) + local res = nil + for i = pos, 1, -1 do + local c = buf:sub(i, i) + if c:find '[%w_]' then + res = i + else + break + end + end + if not res then + for i = pos, 1, -1 do + local c = buf:sub(i, i) + if c == '.' or c == ':' or c == '|' then + res = i + break + elseif c == '#' or c == '@' then + res = i + 1 + break + elseif c:find '[%s%c]' then + else + break + end + end + end + if not res then + return pos + end + return res +end + +local function findWord(position, text) + local word = text + for i = position, 1, -1 do + local c = text:sub(i, i) + if not c:find '[%w_]' then + word = text:sub(i+1, position) + break + end + end + return word:match('^([%w_]*)') +end + +local function getSource(vm, pos, text, filter) + local word = findWord(pos, text) + local source = findSource(vm, pos, filter) + if source then + return source, pos, word + end + pos = findStartPos(pos, text) + source = findSource(vm, pos, filter) + or keywordSource(vm, word, pos) + return source, pos, word +end + +return function (vm, text, pos, oldText) local filter = { ['name'] = true, ['string'] = true, @@ -695,10 +759,7 @@ return function (vm, text, pos, word, oldText) ['emmyIncomplete'] = true, ['call'] = true, } - local source = findSource(vm, pos, filter) - or findSource(vm, pos-1, filter) - or findSource(vm, pos+1, filter) - or keywordSource(vm, word, pos) + local source, pos, word = getSource(vm, pos, text, filter) if not source then return nil end @@ -709,7 +770,7 @@ return function (vm, text, pos, word, oldText) end end local callback, list = makeList(source, pos, word) - if searchToclose(text, word, callback, pos) then + if searchToclose(text, source, word, callback) then return list end searchSpecial(vm, source, word, callback, pos) diff --git a/server/src/core/definition.lua b/server/src/core/definition.lua index a7296bfb..335d2185 100644 --- a/server/src/core/definition.lua +++ b/server/src/core/definition.lua @@ -1,9 +1,8 @@ -local function parseValueSimily(vm, source, lsp) +local function parseValueSimily(callback, vm, source, lsp) local key = source[1] if not key then return nil end - local positions = {} vm:eachSource(function (other) if other == source then goto CONTINUE @@ -14,140 +13,43 @@ local function parseValueSimily(vm, source, lsp) and other:action() == 'set' and source:bindValue() ~= other:bindValue() then - positions[#positions+1] = { - other.start, - other.finish, - } + callback(other) end :: CONTINUE :: end) - if #positions == 0 then - return nil - end - return positions end -local function parseValueCrossFile(vm, source, lsp) +local function parseValueCrossFile(callback, vm, source, lsp) local value = source:bindValue() - local positions = {} - value:eachInfo(function (info, src) - if info.type == 'local' and src.uri == value.uri then - positions[#positions+1] = { - src.start, - src.finish, - value.uri, - } - return true - end - end) - if #positions > 0 then - return positions - end - value:eachInfo(function (info, src) - if info.type == 'set' and src.uri == value.uri then - positions[#positions+1] = { - src.start, - src.finish, - value.uri, - } - end - end) - if #positions > 0 then - return positions - end - - value:eachInfo(function (info, src) - if info.type == 'return' and src.uri == value.uri then - positions[#positions+1] = { - src.start, - src.finish, - value.uri, - } + if src.uri == value.uri then + if info.type == 'local' or info.type == 'set' or info.type == 'return' then + callback(src) + end 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 nil end -local function parseLocal(vm, source, lsp) +local function parseLocal(callback, vm, source, lsp) local positions = {} local loc = source:bindLocal() local locSource = loc:getSource() - if locSource:get 'arg' then - positions[#positions+1] = { - locSource.start, - locSource.finish, - locSource:getUri(), - } - return positions - end + --if locSource:get 'arg' then + -- callback(locSource) + --end local value = source:bindValue() if value and value.uri ~= '' and value.uri ~= vm.uri then - local positions = parseValueCrossFile(vm, source, lsp) - if positions and #positions > 0 then - return positions - end + parseValueCrossFile(callback, vm, source, lsp) end - positions[#positions+1] = { - locSource.start, - locSource.finish, - locSource:getUri(), - } + callback(locSource) if #positions == 0 then return nil end return positions end -local function parseValue(vm, source, lsp) - local positions = {} - local mark = {} - - local function callback(src) - if source == src then - return - end - if mark[src] then - return - end - mark[src] = true - if src.start == 0 then - return - end - local uri = src.uri - if uri == '' then - uri = nil - end - positions[#positions+1] = { - src.start, - src.finish, - uri, - } - end - +local function parseValue(callback, vm, source, lsp) if source:bindValue() then source:bindValue():eachInfo(function (info, src) if info.type == 'set' or info.type == 'local' or info.type == 'return' then @@ -165,56 +67,79 @@ local function parseValue(vm, source, lsp) end end) end - if #positions == 0 then - return nil - end - return positions end -local function parseLabel(vm, label, lsp) - local positions = {} +local function parseLabel(callback, vm, label, lsp) label:eachInfo(function (info, src) if info.type == 'set' then - positions[#positions+1] = { - src.start, - src.finish, - } + callback(src) end end) - if #positions == 0 then - return nil - end - return positions end -local function jumpUri(vm, source, lsp) +local function jumpUri(callback, vm, source, lsp) local uri = source:get 'target uri' - local positions = {} - positions[#positions+1] = { - 0, 0, uri, + callback { + start = 0, + finish = 0, + uri = uri } - return positions +end + +local function parseClass(callback, vm, source) + local className = source:get 'target class' + vm.emmyMgr:eachClass(className, function (class) + local src = class:getSource() + callback(src) + end) +end + +local function makeList(source) + local list = {} + local mark = {} + return list, function (src) + if source == src then + return + end + if mark[src] then + return + end + mark[src] = true + local uri = src.uri + if uri == '' then + uri = nil + end + list[#list+1] = { + src.start, + src.finish, + src.uri + } + end end return function (vm, source, lsp) if not source then return nil end + local list, callback = makeList(source) if source:bindLocal() then - return parseLocal(vm, source, lsp) - end - if source:bindValue() then - return parseValue(vm, source, lsp) - or parseValueSimily(vm, source, lsp) + parseLocal(callback, vm, source, lsp) + elseif source:bindValue() then + parseValue(callback, vm, source, lsp) + --parseValueSimily(callback, vm, source, lsp) end if source:bindLabel() then - return parseLabel(vm, source:bindLabel(), lsp) + parseLabel(callback, vm, source:bindLabel(), lsp) end if source:get 'target uri' then - return jumpUri(vm, source, lsp) + jumpUri(callback, vm, source, lsp) end if source:get 'in index' then - return parseValue(vm, source, lsp) - or parseValueSimily(vm, source, lsp) + parseValue(callback, vm, source, lsp) + --parseValueSimily(callback, vm, source, lsp) + end + if source:get 'target class' then + parseClass(callback, vm, source) end + return list end diff --git a/server/src/core/diagnostics.lua b/server/src/core/diagnostics.lua index d49f8da2..0732b7e3 100644 --- a/server/src/core/diagnostics.lua +++ b/server/src/core/diagnostics.lua @@ -439,10 +439,6 @@ function mt:checkEmmyClass(source, callback) local related = {} local current = class for _ = 1, 10 do - if parent:getName() == class:getName() then - callback(source.start, source.finish, lang.script.DIAG_CYCLIC_EXTENDS, related) - break - end local extends = current.extends if not extends then break @@ -452,20 +448,37 @@ function mt:checkEmmyClass(source, callback) finish = current:getSource().finish, uri = current:getSource().uri, } - current = parent - parent = self.vm.emmyMgr:eachClass(extends, function (parent) + current = self.vm.emmyMgr:eachClass(extends, function (parent) return parent end) - if not parent then + if not current then + break + end + if current:getName() == class:getName() then + callback(source.start, source.finish, lang.script.DIAG_CYCLIC_EXTENDS, related) break end end end +function mt:checkEmmyType(source, callback) + for _, tpsource in ipairs(source) do + local name = tpsource[1] + local class = self.vm.emmyMgr:eachClass(name, function (class) + return class + end) + if not class then + callback(tpsource.start, tpsource.finish, lang.script.DIAG_UNDEFINED_CLASS) + end + end +end + function mt:searchEmmyLua(callback) self.vm:eachSource(function (source) if source.type == 'emmyClass' then self:checkEmmyClass(source, callback) + elseif source.type == 'emmyType' then + self:checkEmmyType(source, callback) end end) end diff --git a/server/src/core/implementation.lua b/server/src/core/implementation.lua index 1b8006b1..450b9a0c 100644 --- a/server/src/core/implementation.lua +++ b/server/src/core/implementation.lua @@ -166,6 +166,20 @@ local function jumpUri(vm, source, lsp) return positions end +local function parseClass(vm, source) + local className = source:get 'target class' + local positions = {} + vm.emmyMgr:eachClass(className, function (class) + local src = class:getSource() + positions[#positions+1] = { + src.start, + src.finish, + src.uri, + } + end) + return positions +end + return function (vm, source, lsp) if not source then return nil @@ -180,4 +194,11 @@ return function (vm, source, lsp) if source:get 'target uri' then return jumpUri(vm, source, lsp) end + if source:get 'in index' then + return parseValue(vm, source, lsp) + or parseValueSimily(vm, source, lsp) + end + if source:get 'target class' then + return parseClass(vm, source) + end end |