diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-01-24 17:20:26 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-01-24 17:20:26 +0800 |
commit | ceb30f6413cf1132ab7fb20355aa4f5a61edc7b6 (patch) | |
tree | 00b08302aad5f3e1b05d6c2e2b22e09be86aee95 | |
parent | fb736f9479b66838da46fc4c002360a1a90761a4 (diff) | |
download | lua-language-server-ceb30f6413cf1132ab7fb20355aa4f5a61edc7b6.zip |
整理代码
-rw-r--r-- | server/src/core/completion.lua | 6 | ||||
-rw-r--r-- | server/src/core/diagnostics.lua | 4 | ||||
-rw-r--r-- | server/src/core/hover.lua | 12 | ||||
-rw-r--r-- | server/src/core/value.lua | 83 | ||||
-rw-r--r-- | server/src/core/vm.lua | 113 |
5 files changed, 131 insertions, 87 deletions
diff --git a/server/src/core/completion.lua b/server/src/core/completion.lua index 2cdd2a64..db9189f0 100644 --- a/server/src/core/completion.lua +++ b/server/src/core/completion.lua @@ -113,10 +113,10 @@ local function searchLocals(vm, pos, name, callback) end local function searchFields(name, source, parent, object, callback) - if not parent or not parent.value or not parent.value.child then + if not parent or not parent.value then return end - for key, field in pairs(parent.value.child) do + parent.value:eachField(function (key, field) if type(key) ~= 'string' then goto CONTINUE end @@ -132,7 +132,7 @@ local function searchFields(name, source, parent, object, callback) callback(field) end ::CONTINUE:: - end + end) end local KEYS = {'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while', 'toclose'} diff --git a/server/src/core/diagnostics.lua b/server/src/core/diagnostics.lua index 64852f03..a00e0d52 100644 --- a/server/src/core/diagnostics.lua +++ b/server/src/core/diagnostics.lua @@ -41,7 +41,7 @@ end function mt:searchUndefinedGlobal(callback) local results = self.results local env = results.locals[1] - for index, field in pairs(env.value.child) do + env.value:eachField(function (index, field) if field.value.lib then goto NEXT_VAR end @@ -66,7 +66,7 @@ function mt:searchUndefinedGlobal(callback) end end ::NEXT_VAR:: - end + end) end function mt:searchUnusedLabel(callback) diff --git a/server/src/core/hover.lua b/server/src/core/hover.lua index b40c6fa4..7c3623fd 100644 --- a/server/src/core/hover.lua +++ b/server/src/core/hover.lua @@ -212,19 +212,19 @@ end local function findClass(result) -- 根据部分字段尝试找出自定义类型 local metatable = result.value.metatable - if not metatable or not metatable.child then + if not metatable then return nil end -- 查找meta表的 __name 字段 - local name = metatable.child['__name'] + local name = metatable:rawGetField('__name') -- 值必须是字符串 if name and name.value and type(name.value.value) == 'string' then return name.value.value end -- 查找meta表 __index 里的字段 - local index = metatable.child['__index'] - if index and index.value and index.value.child then - for key, field in pairs(index.value.child) do + local index = metatable:rawGetField('__index') + if index and index.value then + index.value:eachField(function (key, field) -- 键值类型必须均为字符串 if type(key) ~= 'string' then goto CONTINUE @@ -247,7 +247,7 @@ local function findClass(result) return field.value.value end ::CONTINUE:: - end + end) end return nil end diff --git a/server/src/core/value.lua b/server/src/core/value.lua index 2285738b..9943d282 100644 --- a/server/src/core/value.lua +++ b/server/src/core/value.lua @@ -4,7 +4,82 @@ local mt = {} mt.__index = mt mt.type = 'value' -return function (tp, uri, source, value) +function mt:setValue(source, value) + self.value = value +end + +function mt:inference(tp) + if tp == '...' then + error('Value type cant be ...') + end + if self.type == 'any' and tp ~= 'nil' then + self.type = tp + end +end + +function mt:createField(name, source) + local field = { + type = 'field', + key = name, + source = source or DefaultSource, + } + + if not self._child then + self._child = {} + end + local uri = source and source.uri or '' + if not self._child[uri] then + self._child[uri] = {} + end + self._child[uri][name] = field + + self:inference('table') + + return field +end + +function mt:rawGetField(name, source) + local uri = source and source.uri or '' + local field + if self._child then + if self._child[uri] then + field = self._child[uri][name] + end + if not field then + for _, childs in pairs(self._child) do + field = childs[name] + if field then + break + end + end + end + end +end + +function mt:getField(name, source) + local field = self:rawGetField(name, source) + if not field then + field = self:createField(name, source) + end + return field +end + +function mt:eachField(callback) + if not self._child then + return + end + local mark = {} + for _, childs in pairs(self._child) do + for name, field in pairs(childs) do + if not mark[name] then + mark[name] = true + callback(name, field) + end + end + end +end + +return function (tp, source, value) if tp == '...' then error('Value type cant be ...') end @@ -13,10 +88,10 @@ return function (tp, uri, source, value) tp = tp[1] end local self = setmetatable({ - type = tp, source = source or DefaultSource, - value = value, - uri = uri, }, mt) + if value ~= nil then + self:setValue(source, value) + end return self end diff --git a/server/src/core/vm.lua b/server/src/core/vm.lua index 965a0bec..a4535786 100644 --- a/server/src/core/vm.lua +++ b/server/src/core/vm.lua @@ -199,7 +199,7 @@ function mt:buildTable(source) local key = obj[1] if key.index then local index = self:getIndex(key) - local field = self:createField(tbl, index, key) + local field = tbl:createField(index, key) if value.type == 'list' then self:setValue(field, value[1], key) else @@ -207,7 +207,7 @@ function mt:buildTable(source) end else if key.type == 'name' then - local field = self:createField(tbl, key[1], key) + local field = tbl:createField(key[1], key) self.results.indexs[#self.results.indexs+1] = field key.isIndex = true if value.type == 'list' then @@ -222,17 +222,17 @@ function mt:buildTable(source) if value.type == 'list' then if index == #source then for i, v in ipairs(value) do - local field = self:createField(tbl, n + i) + local field = tbl:createField(n + i) self:setValue(field, v) end else n = n + 1 - local field = self:createField(tbl, n) + local field = tbl:createField(n) self:setValue(field, value[1]) end else n = n + 1 - local field = self:createField(tbl, n) + local field = tbl:createField(n) self:setValue(field, value) end -- 处理写了一半的 key = value,把name类的数组元素视为哈希键 @@ -357,42 +357,11 @@ function mt:getValue(var) return var.value end -function mt:createField(pValue, name, source) - if pValue.type == 'local' or pValue.type == 'field' then - error('Only value can create field') - end - local field = { - type = 'field', - key = name, - source = source or DefaultSource, - } - - if not pValue.child then - pValue.child = orderTable() - end - pValue.child[name] = field - self:inference(pValue, 'table') - return field -end - -function mt:getField(pValue, name, source) - local field = (pValue.child and pValue.child[name]) - if not field and pValue.ENV then - if self.lsp then - field = self.lsp:getGlobal(name) - end - end - if not field then - field = self:createField(pValue, name, source) - end - return field -end - function mt:isGlobal(field) if field.type ~= 'field' then return false end - if field.parent.value.ENV then + if field.parent.value and field.parent.value.ENV then return true else return false @@ -511,8 +480,8 @@ function mt:setFunctionArg(func, values) if not func.argValues[i] then func.argValues[i] = values[i] end - self:inference(values[i], func.argValues[i].type) - self:inference(func.argValues[i], values[i].type) + values[i]:inference(func.argValues[i].type) + func.argValues[i]:inference(values[i].type) end self:updateFunctionArgs(func) @@ -531,7 +500,7 @@ function mt:getFunctionArg(func, i) end function mt:checkMetaIndex(value, meta) - local index = self:getField(meta, '__index') + local index = meta:getField('__index') if not index then return end @@ -674,24 +643,24 @@ function mt:callDoFile(func, values) end function mt:call(func, values) - self:inference(func, 'function') + func:inference('function') local lib = func.lib if lib then if lib.args then for i, arg in ipairs(lib.args) do if arg.type == '...' then - self:inference(self:getFunctionArg(func, i), 'any') + self:getFunctionArg(func, i):inference('any') else - self:inference(self:getFunctionArg(func, i), arg.type or 'any') + self:getFunctionArg(func, i):inference(arg.type or 'any') end end end if lib.returns then for i, rtn in ipairs(lib.returns) do if rtn.type == '...' then - self:inference(self:getFunctionReturns(func, i), 'any') + self:getFunctionReturns(func, i):inference('any') else - self:inference(self:getFunctionReturns(func, i), rtn.type or 'any') + self:getFunctionReturns(func, i):inference(rtn.type or 'any') end end end @@ -772,17 +741,8 @@ function mt:getFunctionReturns(func, i) end end -function mt:inference(value, type) - if type == '...' then - error('Value type cant be ...') - end - if value.type == 'any' and type ~= 'nil' then - value.type = type - end -end - function mt:createValue(tp, source, v) - local value = createValue(tp, self.uri, source, v) + local value = createValue(tp, source, v) local lib = library.object[tp] if lib then self:getLibChild(value, lib, 'object') @@ -798,7 +758,7 @@ function mt:getLibChild(value, lib, parentType) end self.libraryChild[lib] = {} for fName, fLib in pairs(lib.child) do - local fField = self:createField(value, fName) + local fField = value:createField(fName) local fValue = self:getLibValue(fLib, parentType) self:setValue(fField, fValue) end @@ -872,7 +832,7 @@ function mt:getName(name, source) return loc end local ENV = self.scope.locals._ENV - local global = self:getField(self:getValue(ENV), name, source) + local global = self:getValue(ENV):getField(name, source) global.parent = ENV return global end @@ -1001,7 +961,7 @@ function mt:getSimple(simple, mode) elseif tp == 'index' then local child = obj[1] local index = self:getIndex(child) - field = self:getField(value, index, child) + field = value:getField(index, child) field.parentValue = value value = self:getValue(field) if mode == 'value' or i < #simple then @@ -1019,7 +979,7 @@ function mt:getSimple(simple, mode) parentName = ('%s[?]'):format(parentName) end elseif tp == 'name' then - field = self:getField(value, obj[1], obj) + field = value:getField(obj[1], obj) field.parentValue = value value = self:getValue(field) if mode == 'value' or i < #simple then @@ -1055,9 +1015,18 @@ function mt:isTrue(v) return true end +function mt:selectList(list, n) + if list.type ~= 'list' then + return list + end + return list[n] or self:createValue('nil') +end + function mt:getBinary(exp) local v1 = self:getExp(exp[1]) local v2 = self:getExp(exp[2]) + v1 = self:selectList(v1, 1) + v2 = self:selectList(v2, 1) local op = exp.op -- TODO 搜索元方法 if op == 'or' then @@ -1077,8 +1046,8 @@ function mt:getBinary(exp) or op == '<' or op == '>' then - self:inference(v1, 'number') - self:inference(v2, 'number') + v1:inference('number') + v2:inference('number') return self:createValue('boolean') elseif op == '~=' or op == '==' @@ -1090,8 +1059,8 @@ function mt:getBinary(exp) or op == '<<' or op == '>>' then - self:inference(v1, 'integer') - self:inference(v2, 'integer') + v1:inference('integer') + v2:inference('integer') if math.type(v1.value) == 'integer' and math.type(v2.value) == 'integer' then if op == '|' then return self:createValue('integer', v1.value | v2.value) @@ -1107,8 +1076,8 @@ function mt:getBinary(exp) end return self:createValue('integer') elseif op == '..' then - self:inference(v1, 'string') - self:inference(v2, 'string') + v1:inference('string') + v2:inference('string') if type(v1.value) == 'string' and type(v2.value) == 'string' then return self:createValue('string', nil, v1.value .. v2.value) end @@ -1121,8 +1090,8 @@ function mt:getBinary(exp) or op == '%' or op == '//' then - self:inference(v1, 'number') - self:inference(v2, 'number') + v1:inference('number') + v2:inference('number') if type(v1.value) == 'number' and type(v2.value) == 'number' then if op == '+' then return self:createValue('number', nil, v1.value + v2.value) @@ -1158,19 +1127,19 @@ function mt:getUnary(exp) if op == 'not' then return self:createValue('boolean') elseif op == '#' then - self:inference(v1, 'table') + v1:inference('table') if type(v1.value) == 'string' then return self:createValue('integer', nil, #v1.value) end return self:createValue('integer') elseif op == '-' then - self:inference(v1, 'number') + v1:inference('number') if type(v1.value) == 'number' then return self:createValue('number', nil, -v1.value) end return self:createValue('number') elseif op == '~' then - self:inference(v1, 'integer') + v1:inference('integer') if math.type(v1.value) == 'integer' then return self:createValue('integer', nil, ~v1.value) end @@ -1481,7 +1450,7 @@ function mt:createEnvironment() -- 设置全局变量 if not GlobalChild then for name, lib in pairs(library.global) do - local field = self:createField(envValue, name) + local field = envValue:createField(name) local value = self:getLibValue(lib, 'global') value = self:setValue(field, value) end @@ -1490,7 +1459,7 @@ function mt:createEnvironment() envValue.child = readOnly(GlobalChild) -- 设置 _G 使用 _ENV 的child - local g = self:getField(envValue, '_G') + local g = envValue:getField('_G') local gValue = self:getValue(g) gValue.child = envValue.child self.env = envValue |