summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/async/scanfiles.lua82
-rw-r--r--server/src/config.lua8
-rw-r--r--server/src/core/diagnostics.lua6
-rw-r--r--server/src/parser/ast.lua33
-rw-r--r--server/src/parser/grammar.lua10
-rw-r--r--server/src/service.lua9
-rw-r--r--server/src/workspace.lua24
7 files changed, 136 insertions, 36 deletions
diff --git a/server/src/async/scanfiles.lua b/server/src/async/scanfiles.lua
index f53564f8..c242dcfe 100644
--- a/server/src/async/scanfiles.lua
+++ b/server/src/async/scanfiles.lua
@@ -2,17 +2,85 @@ local args = ...
require 'utility'
local fs = require 'bee.filesystem'
-local ignore = { '.git', 'node_modules' }
-
local root = fs.absolute(fs.path(args.root))
-for name in pairs(args.ignore) do
- ignore[#ignore+1] = name
+
+local function glob_compile(pattern)
+ return ("^%s$"):format(pattern:gsub("[%^%$%(%)%%%.%[%]%+%-%?]", "%%%0"):gsub("%*", ".*"))
+end
+local function glob_match(pattern, target)
+ return target:match(pattern) ~= nil
+end
+
+local function accept_path(t, path)
+ if t[path:string()] then
+ return
+ end
+ t[#t+1] = path:string()
+ t[path:string()] = #t
+end
+local function expand_dir(t, pattern, dir)
+ if not fs.exists(dir) then
+ return
+ end
+ for file in dir:list_directory() do
+ if fs.is_directory(file) then
+ expand_dir(t, pattern, file)
+ else
+ if glob_match(pattern, file:filename():string():lower()) then
+ accept_path(t, file)
+ end
+ end
+ end
+end
+local function expand_path(t, root, source)
+ if source:sub(1, 1) == '/' then
+ source = source:sub(2)
+ end
+ local path = root / source
+ if source:find("*", 1, true) == nil then
+ accept_path(t, path)
+ return
+ end
+ local filename = path:filename():string():lower()
+ local pattern = glob_compile(filename)
+ expand_dir(t, pattern, path:parent_path())
+end
+local function get_sources(root, sources)
+ local result = {}
+ local ignore = {}
+ for _, source in ipairs(sources) do
+ if source:sub(1,1) ~= "!" then
+ expand_path(result, root, source)
+ else
+ expand_path(ignore, root, source:sub(2))
+ end
+ end
+ for _, path in ipairs(ignore) do
+ local pos = result[path]
+ if pos then
+ result[pos] = result[#result]
+ result[result[pos]] = pos
+ result[path] = nil
+ result[#result] = nil
+ end
+ end
+ return result
end
-for i, name in ipairs(ignore) do
- ignore[i] = root / name
+
+local function computePath()
+ local ignore = { '.git' }
+
+
+ for name in pairs(args.ignore) do
+ ignore[#ignore+1] = name:lower()
+ end
+
+ return get_sources(root, ignore)
end
-for path in io.scan(root, ignore) do
+local ignored = computePath()
+
+for path in io.scan(root, ignored) do
if path:extension():string() == '.lua' then
local buf = io.load(path)
if buf then
diff --git a/server/src/config.lua b/server/src/config.lua
index a19f17d8..c8d47b2f 100644
--- a/server/src/config.lua
+++ b/server/src/config.lua
@@ -29,11 +29,13 @@ end
local Template = {
diagnostics = {
- globals = {{}, Str2Hash ';'},
- disable = {{}, Str2Hash ';'},
+ globals = {{}, Str2Hash ';'},
+ disable = {{}, Str2Hash ';'},
},
workspace = {
- ignoreDir = {{}, Str2Hash ';'}
+ ignoreDir = {{}, Str2Hash ';'},
+ ignoreSubmodules= {true, Boolean},
+ useGitIgnore = {true, Boolean},
}
}
diff --git a/server/src/core/diagnostics.lua b/server/src/core/diagnostics.lua
index a00e0d52..d0fdbacd 100644
--- a/server/src/core/diagnostics.lua
+++ b/server/src/core/diagnostics.lua
@@ -260,14 +260,14 @@ return function (vm, lines, uri)
-- 未使用的Label
session:doDiagnostics('searchUnusedLabel', 'unused-label', function (key)
return {
- level =DiagnosticSeverity.Information,
+ level =DiagnosticSeverity.Hint,
message = lang.script('DIAG_UNUSED_LABEL', key)
}
end)
-- 只有空格与制表符的行,以及后置空格
session:doDiagnostics('searchSpaces', 'trailing-space', function (message)
return {
- level = DiagnosticSeverity.Information,
+ level = DiagnosticSeverity.Hint,
message = message,
}
end)
@@ -289,7 +289,7 @@ return function (vm, lines, uri)
-- 调用函数时的参数数量是否超过函数的接收数量
session:doDiagnostics('searchRedundantParameters', 'remainder-parameters', function (max, passed)
return {
- level = DiagnosticSeverity.Warning,
+ level = DiagnosticSeverity.Information,
message = lang.script('DIAG_OVER_MAX_ARGS', max, passed),
}
end)
diff --git a/server/src/parser/ast.lua b/server/src/parser/ast.lua
index 48d9eb3b..645d10e9 100644
--- a/server/src/parser/ast.lua
+++ b/server/src/parser/ast.lua
@@ -729,17 +729,24 @@ local Defs = {
BreakEnd = function ()
State.Break = State.Break - 1
end,
- Return = function (exp)
- if exp == nil or exp == '' then
+ Return = function (start, exp, finish)
+ if not finish then
+ finish = exp
exp = {
- type = 'return'
+ type = 'return',
+ start = start,
+ finish = finish - 1,
}
else
if exp.type == 'list' then
exp.type = 'return'
+ exp.start = start
+ exp.finish = finish - 1
else
exp = {
type = 'return',
+ start = start,
+ finish = finish - 1,
[1] = exp,
}
end
@@ -1166,20 +1173,20 @@ local Defs = {
}
return exp
end,
- ActionAfterReturn = function (start, ...)
- if not start or start == '' then
- return
+ AfterReturn = function (rtn, ...)
+ if not ... then
+ return rtn
+ end
+ local action = select(-1, ...)
+ if not action then
+ return rtn
end
- local actions = table.pack(...)
- local max = actions.n
- local finish = actions[max]
- actions[max] = nil
pushError {
type = 'ACTION_AFTER_RETURN',
- start = start,
- finish = finish - 1,
+ start = rtn.start,
+ finish = rtn.finish,
}
- return table.unpack(actions)
+ return rtn, action
end,
}
diff --git a/server/src/parser/grammar.lua b/server/src/parser/grammar.lua
index cd6be11d..17ac4faf 100644
--- a/server/src/parser/grammar.lua
+++ b/server/src/parser/grammar.lua
@@ -401,11 +401,11 @@ Break <- BREAK {} -> Break
BreakStart <- {} -> BreakStart
BreakEnd <- {} -> BreakEnd
-Return <- RETURN MustExpList?
- -> Return (Semicolon / ActionAfterReturn)*
-ActionAfterReturn
- <- (Sp {} (!END !UNTIL !ELSEIF !ELSE Action)+ {})
- -> ActionAfterReturn
+Return <- (ReturnBody Semicolon* AfterReturn?)
+ -> AfterReturn
+ReturnBody <- Sp ({} RETURN MustExpList? {})
+ -> Return
+AfterReturn <- Sp !END !UNTIL !ELSEIF !ELSE Action
Label <- LABEL MustName -> Label DirtyLabel
diff --git a/server/src/service.lua b/server/src/service.lua
index 0eb62121..886eef10 100644
--- a/server/src/service.lua
+++ b/server/src/service.lua
@@ -193,11 +193,12 @@ function mt:readText(uri, path, buf)
end
function mt:removeText(uri)
+ if not self._file[uri] then
+ return
+ end
+ self:saveText(uri, -1, '')
+ self:compileVM(uri)
self._file[uri] = nil
- -- 删除文件后,清除该文件的诊断
- self:clearDiagnostics(uri)
- -- 清除全局变量
- self._global:clearGlobal(uri)
end
function mt:reCompile()
diff --git a/server/src/workspace.lua b/server/src/workspace.lua
index 2fd7ad65..348208ca 100644
--- a/server/src/workspace.lua
+++ b/server/src/workspace.lua
@@ -78,9 +78,31 @@ function mt:init(rootUri)
log.info('Log path: ', logPath)
log.init(ROOT, logPath)
+ local ignored = {}
+ for path in pairs(config.config.workspace.ignoreDir) do
+ ignored[path] = true
+ end
+ if config.config.workspace.ignoreSubmodules then
+ local buf = io.load(self.root / '.gitmodules')
+ if buf then
+ for path in buf:gmatch('path = ([^\r\n]+)') do
+ log.debug('忽略子模块:', path)
+ ignored[path] = true
+ end
+ end
+ end
+ if config.config.workspace.useGitIgnore then
+ local buf = io.load(self.root / '.gitignore')
+ if buf then
+ for line in buf:gmatch '[^\r\n]+' do
+ ignored[line] = true
+ end
+ end
+ end
+
async.run('scanfiles', {
root = self.root:string(),
- ignore = config.config.workspace.ignoreDir,
+ ignore = ignored,
}, function (file)
if file == 'ok' then
self:reset()