Skip to content

Commit 371ec18

Browse files
authored
Merge pull request #373 from julia-vscode/sp/better-followinclude
feat: improve followinclude to check ref
2 parents 444d109 + 9407d75 commit 371ec18

File tree

1 file changed

+71
-53
lines changed

1 file changed

+71
-53
lines changed

src/StaticLint.jl

Lines changed: 71 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -251,73 +251,91 @@ Checks whether the arguments of a call to `include` can be resolved to a path.
251251
If successful it checks whether a file with that path is loaded on the server
252252
or a file exists on the disc that can be loaded.
253253
If this is successful it traverses the code associated with the loaded file.
254-
255254
"""
256255
function followinclude(x, state::State)
257-
if CSTParser.iscall(x) && length(x.args) > 0 && isidentifier(x.args[1]) && valofid(x.args[1]) == "include"
258-
259-
init_path = path = get_path(x, state)
260-
if isempty(path)
261-
elseif isabspath(path)
262-
if hasfile(state.server, path)
263-
elseif canloadfile(state.server, path)
264-
if check_filesize(x, path)
265-
loadfile(state.server, path)
266-
else
267-
return
268-
end
269-
else
270-
path = ""
256+
# this runs on the `include` symbol instead of a function call so that we
257+
# can be sure the ref has already been resolved
258+
isinclude = isincludet = false
259+
p = x
260+
if isidentifier(x) && hasref(x)
261+
r = x.meta.ref
262+
263+
if is_in_fexpr(x, iscall)
264+
p = get_parent_fexpr(x, iscall)
265+
if r == refof_call_func(p)
266+
isinclude = r.name == SymbolServer.VarRef(SymbolServer.VarRef(nothing, :Base), :include)
267+
isincludet = r.name == SymbolServer.VarRef(SymbolServer.VarRef(nothing, :Revise), :includet)
271268
end
272-
elseif !isempty(getpath(state.file)) && isabspath(joinpath(dirname(getpath(state.file)), path))
273-
# Relative path from current
274-
if hasfile(state.server, joinpath(dirname(getpath(state.file)), path))
275-
path = joinpath(dirname(getpath(state.file)), path)
276-
elseif canloadfile(state.server, joinpath(dirname(getpath(state.file)), path))
277-
path = joinpath(dirname(getpath(state.file)), path)
278-
if check_filesize(x, path)
279-
loadfile(state.server, path)
280-
else
281-
return
282-
end
269+
end
270+
end
271+
272+
if !(isinclude || isincludet)
273+
return
274+
end
275+
276+
x = p
277+
278+
init_path = path = get_path(x, state)
279+
if isempty(path)
280+
elseif isabspath(path)
281+
if hasfile(state.server, path)
282+
elseif canloadfile(state.server, path)
283+
if check_filesize(x, path)
284+
loadfile(state.server, path)
283285
else
284-
path = ""
286+
return
285287
end
286-
elseif !isempty((basepath = _is_in_basedir(getpath(state.file)); basepath))
287-
# Special handling for include method used within Base
288-
path = joinpath(basepath, path)
289-
if hasfile(state.server, path)
290-
# skip
291-
elseif canloadfile(state.server, path)
288+
else
289+
path = ""
290+
end
291+
elseif !isempty(getpath(state.file)) && isabspath(joinpath(dirname(getpath(state.file)), path))
292+
# Relative path from current
293+
if hasfile(state.server, joinpath(dirname(getpath(state.file)), path))
294+
path = joinpath(dirname(getpath(state.file)), path)
295+
elseif canloadfile(state.server, joinpath(dirname(getpath(state.file)), path))
296+
path = joinpath(dirname(getpath(state.file)), path)
297+
if check_filesize(x, path)
292298
loadfile(state.server, path)
293299
else
294-
path = ""
300+
return
295301
end
296302
else
297303
path = ""
298304
end
305+
elseif !isempty((basepath = _is_in_basedir(getpath(state.file)); basepath))
306+
# Special handling for include method used within Base
307+
path = joinpath(basepath, path)
299308
if hasfile(state.server, path)
300-
if path in state.included_files
301-
seterror!(x, IncludeLoop)
302-
return
303-
end
304-
f = getfile(state.server, path)
309+
# skip
310+
elseif canloadfile(state.server, path)
311+
loadfile(state.server, path)
312+
else
313+
path = ""
314+
end
315+
else
316+
path = ""
317+
end
318+
if hasfile(state.server, path)
319+
if path in state.included_files
320+
seterror!(x, IncludeLoop)
321+
return
322+
end
323+
f = getfile(state.server, path)
305324

306-
if f.cst.fullspan > LARGE_FILE_LIMIT
307-
seterror!(x, FileTooBig)
308-
return
309-
end
310-
oldfile = state.file
311-
state.file = f
312-
push!(state.included_files, getpath(state.file))
313-
setroot(state.file, getroot(oldfile))
314-
setscope!(getcst(state.file), nothing)
315-
state(getcst(state.file))
316-
state.file = oldfile
317-
pop!(state.included_files)
318-
elseif !is_in_fexpr(x, CSTParser.defines_function) && !isempty(init_path)
319-
seterror!(x, MissingFile)
325+
if f.cst.fullspan > LARGE_FILE_LIMIT
326+
seterror!(x, FileTooBig)
327+
return
320328
end
329+
oldfile = state.file
330+
state.file = f
331+
push!(state.included_files, getpath(state.file))
332+
setroot(state.file, getroot(oldfile))
333+
setscope!(getcst(state.file), nothing)
334+
state(getcst(state.file))
335+
state.file = oldfile
336+
pop!(state.included_files)
337+
elseif !is_in_fexpr(x, CSTParser.defines_function) && !isempty(init_path)
338+
seterror!(x, MissingFile)
321339
end
322340
end
323341

0 commit comments

Comments
 (0)