Skip to content

Commit

Permalink
Merge pull request #17 from Alloyed/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Alloyed authored Sep 8, 2018
2 parents b0fdd66 + a30aed7 commit 0de5118
Show file tree
Hide file tree
Showing 16 changed files with 756 additions and 120 deletions.
11 changes: 10 additions & 1 deletion .luacheckrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
globals = {"Documents", "Types", "Config", "Initialized", "Root", "Shutdown", "Args"}
globals = {
"Args",
"Config",
"Documents",
"Globals",
"Initialized",
"Root",
"Shutdown",
"Types",
}
std="max"

files["spec/*.lua"].std = "+busted"
Expand Down
15 changes: 8 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ language: python
sudo: false

env:
- LUA="lua=5.1"
- LUA="lua=5.2"
- LUA="lua=5.3"
- LUA="luajit=2.0"
- LUA="luajit=2.1"
- LUA="lua=5.3" FMT=""
- LUA="lua=5.1" FMT="lcf"
- LUA="lua=5.1" FMT="formatter"
- LUA="lua=5.2" FMT=""
- LUA="lua=5.3" FMT=""
- LUA="lua=5.3" FMT="lcf"
- LUA="luajit=2.1" FMT=""

cache:
directories:
Expand All @@ -20,8 +22,7 @@ before_install:
install:
- luarocks install --only-deps spec/test-scm-0.rockspec
- luarocks install --only-deps lua-lsp-scm-1.rockspec
- luarocks install Formatter || true
- luarocks install lcf || true
- luarocks install $FMT || true

script:
- luacheck -ur .
Expand Down
112 changes: 86 additions & 26 deletions lua-lsp/analyze.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ local TOPLEVEL = {}
--- turn a luacomplete type into a lsp value
local function translate_luacomplete(into, data)
local function visit_field(key, value, scope)
local Id = {tag = "Id", key, pos=0, posEnd=0, canGoto = false}
local Id = {tag = "Id", key, pos=0, posEnd=0, file = "__NONE__"}
if value.type == "table" then
local fields
if key == TOPLEVEL then
Expand Down Expand Up @@ -73,19 +73,49 @@ local function set(...)
return t
end

local function gen_scopes(len, ast)
local scopes = {setmetatable({},{pos=0, posEnd=len+1, origin="file"})}
for _, builtin in ipairs(Config.builtins) do
local info = require('lua-lsp.data.'..builtin)
if info.global then
translate_luacomplete(scopes[1], info.global)
local GLOBAL_SCOPE = 1
local FILE_SCOPE = 2

local function gen_scopes(len, ast, uri)
if not Globals then
-- FIXME: we need to teach the rest of the system that it's okay for a
-- scopes to not have positions
Globals = setmetatable({},{
id=GLOBAL_SCOPE, pos=0, posEnd=math.huge, origin="global"
})
Globals._G = {{
"_G",
tag = "Id",
pos = 0,
posEnd = 0,
file = "__NONE__",
global = true,
}, {
tag = "Table",
pos = 0,
posEnd = 0,
scope = Globals,
}}
for _, builtin in ipairs(Config.builtins) do
local info = require('lua-lsp.data.'..builtin)
if info.global then
translate_luacomplete(Globals, info.global)
end
end
end

if Config.complete and Config.complete.global then
translate_luacomplete(scopes[1], Config.complete.global)
if Config.complete and Config.complete.global then
translate_luacomplete(Globals, Config.complete.global)
end
end

local scopes = {
Globals,
setmetatable({},{
__index = Globals, id=FILE_SCOPE,
pos=0, posEnd=len+1, origin="file"
}),
}

local visit_stat

local function clean_value(value)
Expand All @@ -99,13 +129,15 @@ local function gen_scopes(len, ast)
tag = value.tag == "String" and "String" or "Literal",
pos = value.pos,
posEnd = value.posEnd,
file = uri,
value = value[1] or value.tag
}
elseif value.tag == "Table" then
return {
tag = value.tag,
pos = value.pos,
posEnd = value.posEnd,
file = uri,
scope = value.scope or {},
}
elseif value.tag == "Call" then
Expand All @@ -129,6 +161,7 @@ local function gen_scopes(len, ast)
tag = value.tag,
pos = value.pos,
posEnd = value.posEnd,
file = uri,
ref = value[1],
_value = value
}
Expand All @@ -138,6 +171,7 @@ local function gen_scopes(len, ast)
tag = value.tag,
pos = value.pos,
posEnd = value.posEnd,
file = uri,
ref = value[1],
_value = value
}
Expand All @@ -146,6 +180,7 @@ local function gen_scopes(len, ast)
tag = value.tag,
pos = value.pos,
posEnd = value.posEnd,
file = uri,
scope = value.scope,
arguments = value[1],
signature = nil
Expand All @@ -155,12 +190,15 @@ local function gen_scopes(len, ast)
tag = value.tag,
pos = value.pos,
posEnd = value.posEnd,
file = uri,
}
elseif value.tag == "Id" then
return { value[1],
tag = value.tag,
pos = value.pos,
posEnd = value.posEnd,
file = uri,
global = value.global,
}
end
--log("unknown obj %t1", value)
Expand Down Expand Up @@ -266,11 +304,13 @@ local function gen_scopes(len, ast)
a[k][2] = clean_value(value)
else
-- this is a new global var
scopes[1][k] = {key, clean_value(value)}
key.global = true
key.file = uri
scopes[GLOBAL_SCOPE][k] = {key, clean_value(value)}
end
end

local function save_return(a, expr)
local function save_return(a, return_node)
-- move the return value up to the closest enclosing scope
local mt
repeat
Expand All @@ -280,7 +320,11 @@ local function gen_scopes(len, ast)
setmetatable(a, mt)
until mt.origin
mt._return = mt._return or {}
table.insert(mt._return, clean_value(expr))
local cleaned_exprs = {}
for _, return_expr in ipairs(return_node) do
table.insert(cleaned_exprs, clean_value(return_expr))
end
table.insert(mt._return, cleaned_exprs)
end

local function visit_expr(node, a)
Expand Down Expand Up @@ -371,17 +415,10 @@ local function gen_scopes(len, ast)
end
end
elseif node.tag == "Return" then
local exprlist = node[1]
if exprlist and exprlist.tag then
local expr = exprlist
for _, expr in ipairs(node) do
visit_expr(expr, a)
save_return(a, expr)
elseif exprlist then
for _, expr in ipairs(exprlist) do
visit_expr(expr, a)
save_return(a, expr)
end
end
save_return(a, node)
elseif node.tag == "Local" then
local namelist,exprlist = node[1], node[2]
if exprlist then
Expand Down Expand Up @@ -439,11 +476,11 @@ local function gen_scopes(len, ast)
end
end
elseif node.tag == "Comment" then
log("found comment <%d, %d>", node.pos, node.posEnd)
log.debug("found comment <%d, %d>", node.pos, node.posEnd)
end
end

visit_stat(ast, scopes[1])
visit_stat(ast, scopes[FILE_SCOPE])
return scopes
end

Expand Down Expand Up @@ -560,7 +597,7 @@ function analyze.refresh(document)
if ast then
document.ast = ast
document.validtext = document.text
document.scopes = gen_scopes(#document.text, document.ast)
document.scopes = gen_scopes(#document.text, document.ast, document.uri)
try_luacheck(document)
else
document.dirty = lcp{document.text, document.validtext}
Expand Down Expand Up @@ -667,7 +704,7 @@ local function add_types(new_types)
end
end

--- load a .luacompleterc file into Config, for later using
--- load a .luacompleterc file into Config, for later use
function analyze.load_completerc(root)
local f = io.open(root.."/.luacompleterc")
if f then
Expand Down Expand Up @@ -711,4 +748,27 @@ function analyze.load_completerc(root)
end
end

--- Create table from vararg, skipping nil values
local function skip(...)
local t = {}
for i=1, select('#', ...) do
-- nil values won't increment length
t[#t+1] = select(i, ...)
end
return t
end

--- Load a .luacheckrc into Config for later use
function analyze.load_luacheckrc(root)
if luacheck then
local cfg = require 'luacheck.config'
-- stack_configs is not in release builds of luacheck yet
if cfg.stack_configs then
local default = cfg.load_config()
local current = cfg.load_config(root.."/.luacheckrc")
Config.luacheckrc = cfg.stack_configs(skip(default, current))
end
end
end

return analyze
43 changes: 33 additions & 10 deletions lua-lsp/formatting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,47 @@

local log = require 'lua-lsp.log'

-- https://luarocks.org/modules/luarocks/formatter
local ok, formatter_or_err = pcall(require, 'formatter')
local drivers = {}

if ok then
local formatter = formatter_or_err
-- https://luarocks.org/modules/luarocks/formatter
drivers['formatter'] = function(formatter)
return {
format = function(text, opts)
return formatter.indentcode(text, "\n", true, opts.indent)
end,
driver = "Formatter"
}
else
-- No-op
end

-- https://github.com/martin-eden/lua_code_formatter
drivers['lcf.workshop.base'] = function()
-- luacheck: globals request
local get_ast = request('!.lua.code.get_ast')
local get_formatted_code = request('!.lua.code.ast_as_code')
return {
format = function(text)
log.warning("No formatter installed!")
return text
format = function(text, opts)
return get_formatted_code(get_ast(text), {
indent_chunk = opts.indent,
})
end,
driver = "noop"
driver = "lcf"
}
end

-- No-op
local noDriver = {
format = function(text)
log.warning("No formatter installed!")
return text
end,
driver = "noop"
}

for mod, driver in pairs(drivers) do
local ok, m_or_err = pcall(require, mod)
if ok then
return driver(m_or_err)
end
end

return noDriver
1 change: 1 addition & 0 deletions lua-lsp/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ function log.debug(...)
--})
end
end
log.d = log.debug

setmetatable(log, {
__call = function(_, ...)
Expand Down
2 changes: 2 additions & 0 deletions lua-lsp/loop.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local method_handlers = require 'lua-lsp.methods'

_G.Types = _G.Types or {}
_G.Documents = _G.Documents or {}
_G.Globals = _G.Globals -- defined in analyze.lua
-- selfish default
_G.Config = _G.Config or {
language = "5.3",
Expand All @@ -24,6 +25,7 @@ local function reload_all()
package.loaded[name] = nil
end
end
log.verbose("===========================")
method_handlers = require 'lua-lsp.methods'
end

Expand Down
Loading

0 comments on commit 0de5118

Please sign in to comment.