Skip to content
3 changes: 1 addition & 2 deletions src/requests/actions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ function explicitly_import_used_variables(x::EXPR, server, conn)

tdes = Dict{String,TextDocumentEdit}()
vars = Set{String}() # names that need to be imported

# Find uses of `x` and mark edits
for ref in refof(x).refs
if parentof(ref) isa EXPR && typof(parentof(ref)) == CSTParser.BinaryOpCall && length(parentof(ref).args) == 3 && kindof(parentof(ref).args[2]) === CSTParser.Tokens.DOT && parentof(ref).args[1] == ref
typof(parentof(ref).args[3]) !== CSTParser.Quotenode && continue # some malformed EXPR, skip
childname = parentof(ref).args[3].args[1]
StaticLint.hasref(childname) && refof(childname) isa StaticLint.Binding && continue # check this isn't the name of something being explictly overwritten
!haskey(refof(x).val.vals, valof(childname)) && continue # skip, perhaps mark as missing ref ?
!haskey(refof(x).val.vals, Symbol(valof(childname))) && continue # skip, perhaps mark as missing ref ?

file, offset = get_file_loc(ref)
if !haskey(tdes, file._uri)
Expand Down
45 changes: 45 additions & 0 deletions test/requests/actions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
action_request_test(line0, char0, line1 = line0, char1 = char0; diags = []) = LanguageServer.textDocument_codeAction_request(LanguageServer.CodeActionParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Range(LanguageServer.Position(line0, char0), LanguageServer.Position(line1, char1)), LanguageServer.CodeActionContext(diags, missing)), server, server.jr_endpoint)

@testset "reexport" begin
settestdoc("using Base.Meta\n")
@test any(c.command == "ReexportModule" for c in action_request_test(0, 15))
c = filter(c->c.command == "ReexportModule", action_request_test(0, 15))[1]

LanguageServer.workspace_executeCommand_request(LanguageServer.ExecuteCommandParams(missing, c.command, c.arguments), server, server.jr_endpoint)
end

@testset "inline expand" begin
settestdoc("f(x) = x")
@test any(c.command == "ExpandFunction" for c in action_request_test(0, 5))
c = filter(c->c.command == "ExpandFunction", action_request_test(0, 5))[1]

LanguageServer.workspace_executeCommand_request(LanguageServer.ExecuteCommandParams(missing, c.command, c.arguments), server, server.jr_endpoint)

settestdoc("f(x) = begin x end")
@test any(c.command == "ExpandFunction" for c in action_request_test(0, 5))
c = filter(c->c.command == "ExpandFunction", action_request_test(0, 5))[1]

LanguageServer.workspace_executeCommand_request(LanguageServer.ExecuteCommandParams(missing, c.command, c.arguments), server, server.jr_endpoint)
end

@testset "fixmissingref" begin
doc = settestdoc("argtail\n")
e = LanguageServer.mark_errors(doc)[1]
@test any(c.command == "FixMissingRef" for c in action_request_test(0, 5, diags = [e]))
c = filter(c->c.command == "FixMissingRef", action_request_test(0, 5, diags = [e]))[1]

LanguageServer.workspace_executeCommand_request(LanguageServer.ExecuteCommandParams(missing, c.command, c.arguments), server, server.jr_endpoint)
end

@testset "explicit import" begin
doc = settestdoc("using Base.Meta\nMeta.quot")
@test LanguageServer.find_using_statement(doc.cst[2][1]) !== nothing

@test any(c.command == "ExplicitPackageVarImport" for c in action_request_test(1, 1))
c = filter(c->c.command == "ExplicitPackageVarImport", action_request_test(1, 1))[1]

LanguageServer.workspace_executeCommand_request(LanguageServer.ExecuteCommandParams(missing, c.command, c.arguments), server, server.jr_endpoint)
end



125 changes: 125 additions & 0 deletions test/requests/completions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
completion_test(line, char) = LanguageServer.textDocument_completion_request(LanguageServer.CompletionParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Position(line, char), missing), server, server.jr_endpoint)

@testset "latex completions" begin
settestdoc("""
\\therefor
.\\therefor
#\\therefor
"\\therefor"
\"\"\"\\therefor\"\"\"
^\\therefor
""")
@test completion_test(0, 9).items[1].textEdit.newText == "∴"
@test completion_test(0, 9).items[1].textEdit.range == LanguageServer.Range(0, 0, 0, 9)

@test completion_test(1, 10).items[1].textEdit.newText == "∴"
@test completion_test(1, 10).items[1].textEdit.range == LanguageServer.Range(1, 1, 1, 10)

@test completion_test(2, 10).items[1].textEdit.newText == "∴"
@test completion_test(2, 10).items[1].textEdit.range == LanguageServer.Range(2, 1, 2, 10)

@test completion_test(3, 10).items[1].textEdit.newText == "∴"
@test completion_test(3, 10).items[1].textEdit.range == LanguageServer.Range(3, 1, 3, 10)

@test completion_test(4, 12).items[1].textEdit.newText == "∴"
@test completion_test(4, 12).items[1].textEdit.range == LanguageServer.Range(4, 3, 4, 12)

@test completion_test(5, 10).items[1].textEdit.newText == "∴"
@test completion_test(5, 10).items[1].textEdit.range == LanguageServer.Range(5, 1, 5, 10)
end

@testset "path completions" begin
end

@testset "import completions" begin
settestdoc("import Base: r")
@test any(item.label == "rand" for item in completion_test(0, 14).items)

settestdoc("import ")
@test all(item.label in ("Main", "Base", "Core") for item in completion_test(0, 7).items)

settestdoc("""module M end
import .""")
@test_broken completion_test(1, 8).items[1].label == "M"

settestdoc("import Base.")
@test any(item.label == "Meta" for item in completion_test(0, 12).items)

settestdoc("import Base.M")
@test any(item.label == "Meta" for item in completion_test(0, 13).items)

settestdoc("import Bas")
@test any(item.label == "Base" for item in completion_test(0, 10).items)
end

@testset "getfield completions" begin
settestdoc("Base.")
@test any(item.label == "Base" for item in completion_test(0, 5).items)

settestdoc("Base.r")
@test any(item.label == "rand" for item in completion_test(0, 6).items)

settestdoc("""
using Base.Meta
Base.Meta.
""")
@test any(item.label == "quot" for item in completion_test(1, 10).items)

settestdoc("""
module M
inner = 1
end
M.
""")
@test any(item.label == "inner" for item in completion_test(3, 2).items)

settestdoc("""
x = Expr()
x.
""")
@test all(item.label in ("head", "args") for item in completion_test(1, 2).items)

settestdoc("""
struct T
f1
f2
end
x = T()
x.
""")
@test all(item.label in ("f1", "f2") for item in completion_test(1, 2).items)
end



@testset "token completions" begin
settestdoc("B")
@test any(item.label == "Base" for item in completion_test(0, 1).items)

settestdoc("r")
@test any(item.label == "rand" for item in completion_test(0, 1).items)

settestdoc("@t")
@test any(item.label == "@time" for item in completion_test(0, 2).items)

settestdoc("i")
@test any(item.label == "if" for item in completion_test(0, 1).items)

settestdoc("i")
@test any(item.label == "in" for item in completion_test(0, 1).items)

settestdoc("for")
@test any(item.label == "for" for item in completion_test(0, 3).items)

settestdoc("in")
@test any(item.label == "in" for item in completion_test(0, 2).items)

settestdoc("isa")
@test any(item.label == "isa" for item in completion_test(0, 3).items)
end

@testset "scope var completions" begin
settestdoc("""myvar = 1
myv""")
@test any(item.label == "myvar" for item in completion_test(1, 3).items)
end
100 changes: 100 additions & 0 deletions test/requests/features.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
sig_test(line, char) = LanguageServer.textDocument_signatureHelp_request(LanguageServer.TextDocumentPositionParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Position(line, char)), server, server.jr_endpoint)

def_test(line, char) = LanguageServer.textDocument_definition_request(LanguageServer.TextDocumentPositionParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Position(line, char)), server, server.jr_endpoint)

ref_test(line, char) = LanguageServer.textDocument_references_request(LanguageServer.ReferenceParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Position(line, char), missing, missing, LanguageServer.ReferenceContext(true)), server, server.jr_endpoint)

rename_test(line, char) = LanguageServer.textDocument_rename_request(LanguageServer.RenameParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Position(line, char), missing, "newname"), server, server.jr_endpoint)


@testset "signatures" begin
doc = settestdoc("""
rand()
Base.rand()
func(arg) = 1
func()
struct T
a
b
end
T()
struct S{R}
a
S() = new(1)
end
using Base:argtail
argtail()
S{R}()
""")
@test !isempty(sig_test(0, 5).signatures)
@test !isempty(sig_test(1, 10).signatures)
@test !isempty(sig_test(3, 5).signatures)
@test !isempty(sig_test(8, 2).signatures)
@test_broken !isempty(sig_test(15, 5).signatures)

let sigs = LanguageServer.SignatureInformation[]
LanguageServer.get_signatures(doc.cst[3].meta.binding, doc.cst.meta.scope, sigs, server)
@test length(sigs) == 1
end
let sigs = LanguageServer.SignatureInformation[]
LanguageServer.get_signatures(doc.cst[5].meta.binding, doc.cst.meta.scope, sigs, server)
@test length(sigs) == 1
end
let sigs = LanguageServer.SignatureInformation[]
LanguageServer.get_signatures(doc.cst[1][1].meta.ref, doc.cst.meta.scope, sigs, server)
@test length(sigs) > 0
end
let sigs = LanguageServer.SignatureInformation[]
LanguageServer.get_signatures(doc.cst[7].meta.binding, doc.cst.meta.scope, sigs, server)
@test length(sigs) == 1
end
let sigs = LanguageServer.SignatureInformation[]
LanguageServer.get_signatures(doc.cst[9][1].meta.ref, doc.cst.meta.scope, sigs, server)
@test length(sigs) == 1
end
end

@testset "definitions" begin
settestdoc("""
rand()
func(arg) = 1
func()
Float64
""")
# @test !isempty(def_test(0, 3))
@test !isempty(def_test(2, 3))
@test !isempty(def_test(3, 3))
end

@testset "references" begin
settestdoc("""
func(arg) = 1
func()
""")
@test length(ref_test(1, 2)) == 2
end

@testset "rename" begin
settestdoc("""
func(arg) = 1
func()
""")
@test length(rename_test(0, 2).documentChanges[1].edits) == 2
end

@testset "get_file_loc" begin
doc = settestdoc("""
func(arg) = 1
func()
""")
@test LanguageServer.get_file_loc(doc.cst.args[2].args[1]) == (doc, 14)
end

@testset "doc symbols" begin
doc = settestdoc("""
a = 1
b = 2
function func() end
""")
@test all(item.name in ("a", "b", "func") for item in LanguageServer.textDocument_documentSymbol_request(LanguageServer.DocumentSymbolParams(LanguageServer.TextDocumentIdentifier("testdoc"), missing, missing), server, server.jr_endpoint))
end
47 changes: 47 additions & 0 deletions test/requests/hover.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
hover_test(line, char) = LanguageServer.textDocument_hover_request(LanguageServer.TextDocumentPositionParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Position(line, char)), server, server.jr_endpoint)

settestdoc("""
1234
Base
+
vari = 1234
\"\"\"
Text
\"\"\"
function func(arg) end
func() = nothing
module M end
struct T end
mutable struct T end
for i = 1:1 end
while true end
begin end
sin()
struct S
a
b
c
d
e
f
g
end
S(a,b,c,d,e,f,g)
""")

@test hover_test(0, 1) === nothing
@test hover_test(1, 1) !== nothing
@test hover_test(2, 1) !== nothing
@test hover_test(3, 1) !== nothing
@test hover_test(7, 11) !== nothing
@test hover_test(8, 2) !== nothing
@test hover_test(7, 16) !== nothing
@test hover_test(7, 20) !== nothing
@test hover_test(9, 11) !== nothing
@test hover_test(10, 11) !== nothing
@test hover_test(11, 18) !== nothing
@test hover_test(12, 14) !== nothing
@test hover_test(13, 13) !== nothing
@test hover_test(14, 7) !== nothing
@test hover_test(15, 5) !== nothing
@test hover_test(25, 15) !== nothing
12 changes: 12 additions & 0 deletions test/requests/misc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@testset "getCurrentBlockRange" begin
doc = settestdoc("ab")

res = (LanguageServer.Position(0, 0), LanguageServer.Position(0, 2), LanguageServer.Position(0, 2))

@test LanguageServer.julia_getCurrentBlockRange_request(LanguageServer.VersionedTextDocumentPositionParams(LanguageServer.TextDocumentIdentifier("testdoc"), 0,LanguageServer.Position(0, 0)), server, server.jr_endpoint) == res

@test LanguageServer.julia_getCurrentBlockRange_request(LanguageServer.VersionedTextDocumentPositionParams(LanguageServer.TextDocumentIdentifier("testdoc"), 0,LanguageServer.Position(0, 1)), server, server.jr_endpoint) == res

@test LanguageServer.julia_getCurrentBlockRange_request(LanguageServer.VersionedTextDocumentPositionParams(LanguageServer.TextDocumentIdentifier("testdoc"), 0,LanguageServer.Position(0, 2)), server, server.jr_endpoint) == res
end

15 changes: 15 additions & 0 deletions test/requests/textdocument.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
empty!(server._documents)

LanguageServer.textDocument_didOpen_notification(LanguageServer.DidOpenTextDocumentParams(LanguageServer.TextDocumentItem("none", "julia", 0, "")), server, server.jr_endpoint)
@test LanguageServer.hasdocument(server, LanguageServer.URI2("none"))

LanguageServer.textDocument_didOpen_notification(LanguageServer.DidOpenTextDocumentParams(LanguageServer.TextDocumentItem("none", "julia", 0, "")), server, server.jr_endpoint)
@test LanguageServer.hasdocument(server, LanguageServer.URI2("none"))

LanguageServer.textDocument_didSave_notification(LanguageServer.DidSaveTextDocumentParams(LanguageServer.TextDocumentIdentifier("none"), ""), server, server.jr_endpoint)

LanguageServer.textDocument_didChange_notification(LanguageServer.DidChangeTextDocumentParams(LanguageServer.VersionedTextDocumentIdentifier("none", 0),[LanguageServer.TextDocumentContentChangeEvent(missing, missing, "ran")]), server, server.jr_endpoint)


LanguageServer.textDocument_didClose_notification(LanguageServer.DidCloseTextDocumentParams(LanguageServer.TextDocumentIdentifier("none")), server, server.jr_endpoint)
@test !LanguageServer.hasdocument(server, LanguageServer.URI2("none"))
Loading