diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2018-12-28 15:36:56 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2018-12-28 15:36:56 +0800 |
commit | a080b2516d2ce2efb65ad0fd26126cdfa6f6e4f8 (patch) | |
tree | b5672e03d11a43a56b63fe02d7b685eacd21ace4 /server/src/core/library.lua | |
parent | 549f6dd7ce8c733f9b51f5e93b3f14c1e2a44aca (diff) | |
download | lua-language-server-a080b2516d2ce2efb65ad0fd26126cdfa6f6e4f8.zip |
matcher -> core
Diffstat (limited to 'server/src/core/library.lua')
-rw-r--r-- | server/src/core/library.lua | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/server/src/core/library.lua b/server/src/core/library.lua new file mode 100644 index 00000000..b268b368 --- /dev/null +++ b/server/src/core/library.lua @@ -0,0 +1,177 @@ +local lni = require 'lni' +local fs = require 'bee.filesystem' + +local function mergeEnum(lib, locale) + if not lib or not locale then + return + end + local pack = {} + for _, enum in ipairs(lib) do + if enum.enum then + pack[enum.enum] = enum + end + if enum.code then + pack[enum.code] = enum + end + end + for _, enum in ipairs(locale) do + if pack[enum.enum] then + if enum.description then + pack[enum.enum].description = enum.description + end + end + if pack[enum.code] then + if enum.description then + pack[enum.code].description = enum.description + end + end + end +end + +local function mergeField(lib, locale) + if not lib or not locale then + return + end + local pack = {} + for _, field in ipairs(lib) do + if field.field then + pack[field.field] = field + end + end + for _, field in ipairs(locale) do + if pack[field.field] then + if field.description then + pack[field.field].description = field.description + end + end + end +end + +local function mergeLocale(libs, locale) + if not libs or not locale then + return + end + for name in pairs(locale) do + if libs[name] then + if locale[name].description then + libs[name].description = locale[name].description + end + mergeEnum(libs[name].enums, locale[name].enums) + mergeField(libs[name].fields, locale[name].fields) + end + end +end + +local function mergeSource(alllibs, name, lib) + if not lib.source then + alllibs.global[name] = lib + return + end + for _, source in ipairs(lib.source) do + local sourceName = source.name or name + if source.type == 'global' then + alllibs.global[sourceName] = lib + elseif source.type == 'library' then + alllibs.library[sourceName] = lib + elseif source.type == 'object' then + alllibs.object[sourceName] = lib + end + end +end + +local function copy(t) + local new = {} + for k, v in pairs(t) do + new[k] = v + end + return new +end + +local function insert(tbl, name, key, value) + if not name or not key then + return + end + if not tbl[name] then + tbl[name] = { + type = name, + name = name, + child = {}, + } + end + tbl[name].child[key] = copy(value) +end + +local function mergeParent(alllibs, name, lib) + for _, parent in ipairs(lib.parent) do + if parent.type == 'global' then + insert(alllibs.global, parent.name, name, lib) + elseif parent.type == 'library' then + insert(alllibs.library, parent.name, name, lib) + elseif parent.type == 'object' then + insert(alllibs.object, parent.name, name, lib) + end + end +end + +local function mergeLibs(alllibs, libs) + if not libs then + return + end + for _, lib in pairs(libs) do + if lib.parent then + mergeParent(alllibs, lib.name, lib) + else + mergeSource(alllibs, lib.name, lib) + end + end +end + +local function loadLocale(language, relative) + local localePath = ROOT / 'locale' / language / relative + local localeBuf = io.load(localePath) + if localeBuf then + local locale = table.container() + xpcall(lni.classics, log.error, localeBuf, localePath:string(), {locale}) + return locale + end + return nil +end + +local function fix(libs) + for name, lib in pairs(libs) do + lib.name = lib.name or name + lib.child = {} + end +end + +local function init() + local lang = require 'language' + local id = lang.id + local alllibs = { + global = table.container(), + library = table.container(), + object = table.container(), + } + for path in io.scan(ROOT / 'libs') do + local libs + local buf = io.load(path) + if buf then + libs = table.container() + xpcall(lni.classics, log.error, buf, path:string(), {libs}) + fix(libs) + end + local relative = fs.relative(path, ROOT) + + local locale = loadLocale('en-US', relative) + mergeLocale(libs, locale) + if id ~= 'en-US' then + locale = loadLocale(id, relative) + mergeLocale(libs, locale) + end + mergeLibs(alllibs, libs) + end + + return alllibs +end + +return init() |