Skip to content

Commit

Permalink
Merge pull request #261 from julia-vscode/struct-params
Browse files Browse the repository at this point in the history
stop overwriting struct params
  • Loading branch information
davidanthoff authored Feb 10, 2021
2 parents 00fedf4 + 3e6c1e4 commit 1117b1e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
41 changes: 26 additions & 15 deletions src/bindings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,29 @@ function mark_binding!(x::EXPR, val=x)
return x
end


function mark_parameters(sig::EXPR)
signame = CSTParser.rem_where_subtype(sig)
if CSTParser.iscurly(signame)
for i = 2:length(signame.args)
mark_binding!(signame.args[i])
function mark_parameters(sig::EXPR, params = String[])
if CSTParser.issubtypedecl(sig)
mark_parameters(sig.args[1], params)
elseif iswhere(sig)
for i = 2:length(sig.args)
x = mark_binding!(sig.args[i])
val = valof(bindingof(x).name)
if val isa String
push!(params, val)
end
end
mark_parameters(sig.args[1], params)
elseif CSTParser.iscurly(sig)
for i = 2:length(sig.args)
x = mark_binding!(sig.args[i])
if valof(bindingof(x).name) in params
# Don't mark a new binding if a parameter has already been
# introduced from a :where
x.meta.binding = nothing
end
end
end
return sig
sig
end


Expand Down Expand Up @@ -231,18 +245,15 @@ function is_in_funcdef(x)
end
end

function _in_func_def(x::EXPR)
rem_wheres_subs_decls(x::EXPR) = (iswhere(x) || isdeclaration(x) || CSTParser.issubtypedecl(x)) ? rem_wheres_subs_decls(x.args[1]) : x

function _in_func_or_struct_def(x::EXPR)
# only called in :where
# check 1st arg contains a call (or op call)
ex = CSTParser.rem_wheres_decls(x.args[1])

!(CSTParser.iscall(ex) || CSTParser.is_getfield(ex) || CSTParser.isunarycall(ex)) && return false

# check parent is func def
return is_in_funcdef(x)
ex = rem_wheres_subs_decls(x.args[1])
is_in_fexpr(x, CSTParser.defines_struct) || ((CSTParser.iscall(ex) || CSTParser.is_getfield(ex) || CSTParser.isunarycall(ex)) && is_in_funcdef(x))
end


"""
add_binding(x, state, scope=state.scope)
Expand Down
2 changes: 1 addition & 1 deletion src/scope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function introduces_scope(x::EXPR, state)
return true
elseif CSTParser.iswhere(x)
# unless in func def signature
return !_in_func_def(x)
return !_in_func_or_struct_def(x)
elseif CSTParser.istuple(x) && CSTParser.hastrivia(x) && ispunctuation(x.trivia[1]) && length(x.args) > 0 && isassignment(x.args[1])
# named tuple
return true
Expand Down
15 changes: 15 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1543,3 +1543,18 @@ end
StaticLint.clear_meta(cst[1])
@test bindingof(cst[2][2][3]).type === nothing
end

@testset "clear .type refs" begin
cst = parse_and_pass("""
struct T{S,R} where S <: Number where R <: Number
end
""")
@test isempty(StaticLint.collect_hints(cst, server))

cst = parse_and_pass("""
struct T{S,R} <: Number where S <: Number
x::S
end
""")
@test isempty(StaticLint.collect_hints(cst, server))
end

0 comments on commit 1117b1e

Please sign in to comment.