Skip to content

Commit 4d990b6

Browse files
authored
Fix diagnostics printing when pwd() doesn't exist (#373)
Computing the file URL for pretty printing using `abspath` can fail when the current working directory doesn't exist. This is a quick fix for this issue (which is incredibly confusing/disruptive if the user does manage to enter a nonexistant working directory!) A more complete fix would avoid ever looking at the working directory when printing diagnostics, instead requiring the caller to pass in a richer definition of the "location of source code" than the mere file name as a string. However getting something sensible working there is (a) breaking and (b) unclear on may details. So just patching this up quickly seems good for now.
1 parent 1b048aa commit 4d990b6

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

src/diagnostics.jl

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,26 @@ Base.range(d::Diagnostic) = first_byte(d):last_byte(d)
4444

4545
# Make relative path into a file URL
4646
function _file_url(filename)
47-
@static if Sys.iswindows()
48-
# TODO: Test this with windows terminal
49-
path = replace(abspath(filename), '\\'=>'/')
50-
else
51-
path = abspath(filename)
47+
try
48+
@static if Sys.iswindows()
49+
# TODO: Test this with windows terminal
50+
path = replace(abspath(filename), '\\'=>'/')
51+
else
52+
path = abspath(filename)
53+
end
54+
return "file://$(path)"
55+
catch exc
56+
# abspath may fail if working directory doesn't exist
57+
# TODO: It seems rather non-ideal to have the behavior here depend on
58+
# the state of the local filesystem. And yet links in diagnostics seem
59+
# useful.
60+
#
61+
# Ideally it'd be up to the caller to provide some notion of the
62+
# "absolute location" of the source code resource when SourceFile is
63+
# constructed. This is often not related to the local filesystem - it
64+
# could be in memory, a fragment embedded in another file, etc etc.
65+
return nothing
5266
end
53-
"file://$(path)"
5467
end
5568

5669
function show_diagnostic(io::IO, diagnostic::Diagnostic, source::SourceFile)
@@ -64,8 +77,11 @@ function show_diagnostic(io::IO, diagnostic::Diagnostic, source::SourceFile)
6477
file_href = nothing
6578
if !isnothing(filename)
6679
locstr = "$filename:$linecol"
67-
if !startswith(filename, "REPL[")
68-
file_href = _file_url(filename)*"#$linecol"
80+
if !startswith(filename, "REPL[") && get(io, :color, false)
81+
url = _file_url(filename)
82+
if !isnothing(url)
83+
file_href = url*"#$linecol"
84+
end
6985
end
7086
else
7187
locstr = "line $linecol"

test/diagnostics.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,25 @@ end
218218
# Error @ line 1:8
219219
a -- b -- c
220220
# └┘ ── invalid operator"""
221+
222+
stream = JuliaSyntax.ParseStream("a -- b")
223+
JuliaSyntax.parse!(stream)
224+
fname = "test.jl"
225+
sf = SourceFile(stream, filename=fname)
226+
url = JuliaSyntax._file_url(fname)
227+
@test sprint(JuliaSyntax.show_diagnostics, stream.diagnostics, sf,
228+
context=:color=>true) == """
229+
\e[90m# Error @ \e[0;0m\e]8;;$url#1:3\e\\\e[90mtest.jl:1:3\e[0;0m\e]8;;\e\\
230+
a \e[48;2;120;70;70m--\e[0;0m b
231+
\e[90m# └┘ ── \e[0;0m\e[91minvalid operator\e[0;0m"""
232+
233+
if Sys.isunix()
234+
mktempdir() do tempdirname
235+
cd(tempdirname) do
236+
rm(tempdirname)
237+
# Test _file_url doesn't fail with nonexistant directories
238+
@test isnothing(JuliaSyntax._file_url(joinpath("__nonexistant__", "test.jl")))
239+
end
240+
end
241+
end
221242
end

0 commit comments

Comments
 (0)