Skip to content

Commit e068ee3

Browse files
committed
add lint messages
1 parent 84486bb commit e068ee3

File tree

4 files changed

+44
-25
lines changed

4 files changed

+44
-25
lines changed

src/StaticLint.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mutable struct Reference{T}
2020
end
2121

2222
include("bindings.jl")
23+
include("linting.jl")
2324

2425
mutable struct ResolvedRef{T, S}
2526
r::Reference{T}
@@ -59,10 +60,11 @@ mutable struct State
5960
used_modules::Vector{Binding}
6061
refs::Vector{Reference}
6162
includes::Vector{Include}
63+
linterrors::Vector{LintError}
6264
server
6365
end
64-
State() = State(Location("", 0), Dict{Tuple,Dict}(), ModuleList(), Dict{Tuple,Vector}(),ImportBinding[], Binding[], Reference[], Include[], DocumentServer())
65-
State(path::String, server) = State(Location(path, 0), Dict{Tuple,Any}(), ModuleList(), Dict{Tuple,Vector}(),ImportBinding[], Binding[], Reference[], Include[], server)
66+
State() = State(Location("", 0), Dict{Tuple,Dict}(), ModuleList(), Dict{Tuple,Vector}(),ImportBinding[], Binding[], Reference[], Include[], LintError[], DocumentServer())
67+
State(path::String, server) = State(Location(path, 0), Dict{Tuple,Any}(), ModuleList(), Dict{Tuple,Vector}(),ImportBinding[], Binding[], Reference[], Include[], LintError[], server)
6668

6769
mutable struct File
6870
cst::CSTParser.EXPR
@@ -110,9 +112,6 @@ function pass(x, state::State, s::Scope, index, blockref, delayed)
110112
ext_binding(x, state, s) # Get external bindings generated by `x`.
111113
s1 = create_scope(x, state, s) # Create new scope (if needed) for traversing through `x`.
112114
delayed = delayed || s1.t == CSTParser.FunctionDef || x isa CSTParser.EXPR{CSTParser.Export} # Internal scope evaluation is delayed
113-
# if delayed && (x isa CSTParser.BinarySyntaxOpCall && x.op.kind == CSTParser.Tokens.DECLARATION)
114-
# delayed = false
115-
# end
116115
get_include(x, state, s1) # Check whether `x` includes a file.
117116
for a in x # Traverse sub expressions of `x`.
118117
ablockref = get_ref(a, state, s1, blockref, delayed)
@@ -158,6 +157,7 @@ function pass(file::File)
158157
empty!(file.state.imports)
159158
empty!(file.state.exports)
160159
empty!(file.state.used_modules)
160+
empty!(file.state.linterrors)
161161
file.scope = Scope(nothing, Scope[], file.cst.span, CSTParser.TopLevel, file.index, file.nb)
162162
file.scope = pass(file.cst, file.state, file.scope, file.index, false, false)
163163
end
@@ -166,7 +166,6 @@ include("references.jl")
166166
include("utils.jl")
167167
include("documentserver.jl")
168168
include("helpers.jl")
169-
include("infer.jl")
170169
include("display.jl")
171170

172171
end

src/bindings.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ end
449449

450450

451451
function _get_field(par, arg, state)
452-
if par isa Dict
452+
if par isa Dict #package store
453453
if haskey(par, CSTParser.str_value(arg))
454454
par = par[CSTParser.str_value(arg)]
455455
if par isa String # reference to dependency
@@ -463,7 +463,7 @@ function _get_field(par, arg, state)
463463
else
464464
return
465465
end
466-
elseif par isa SymbolServer.ModuleStore
466+
elseif par isa SymbolServer.ModuleStore # imported module
467467
if haskey(par.vals, CSTParser.str_value(arg))
468468
par = par.vals[CSTParser.str_value(arg)]
469469
if par isa String # reference to dependency
@@ -485,7 +485,7 @@ function _get_field(par, arg, state)
485485
par = last(ret)
486486
return par
487487
end
488-
else
488+
elseif par isa Binding
489489
ind = add_to_tuple(par.si.i, par.si.n + 1)
490490
ret = find_binding(state.bindings, CSTParser.str_value(arg), ind, x->true)
491491
if isempty(ret)
Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,45 @@
1-
function infer(b, server, rrefs)
1+
@enum(LintCode, IncludeFail)
2+
const LintMessages = Dict{LintCode,String}(
3+
IncludeFail => "Cannot include file."
4+
)
5+
6+
struct LintError
7+
code::LintCode
8+
loc::Location
9+
val::CSTParser.AbstractEXPR
10+
end
11+
12+
function infer_literal(x::CSTParser.LITERAL, server)
13+
if x.kind == CSTParser.Tokenize.Tokens.STRING || x.kind == CSTParser.Tokenize.Tokens.TRIPLE_STRING
14+
return server.packages["Core"].vals["String"]
15+
elseif x.kind == CSTParser.Tokenize.Tokens.INTEGER
16+
return server.packages["Core"].vals["Int"]
17+
elseif x.kind == CSTParser.Tokenize.Tokens.FLOAT
18+
return server.packages["Core"].vals["Float64"]
19+
elseif x.kind == CSTParser.Tokenize.Tokens.HEX_INT || x.kind == CSTParser.Tokenize.Tokens.OCT_INT || x.kind == CSTParser.Tokenize.Tokens.BIN_INT
20+
return server.packages["Core"].vals["UInt64"]
21+
elseif x.kind == CSTParser.Tokenize.Tokens.CHAR
22+
return server.packages["Core"].vals["Char"]
23+
end
24+
end
225

26+
27+
function infer(b, server, rrefs)
328
if b.t isa Binding || b.t isa SymbolServer.SymStore
429
# type already known
530
return
631
elseif b.val isa CSTParser.BinarySyntaxOpCall && b.val.op.kind == CSTParser.Tokenize.Tokens.EQ # assignment
732
if b.val.arg2 isa CSTParser.LITERAL
833
# rhs is a literal, inference is trivial
9-
if b.val.arg2.kind == CSTParser.Tokenize.Tokens.STRING || b.val.arg2.kind == CSTParser.Tokenize.Tokens.TRIPLE_STRING
10-
b.t = server.packages["Core"].vals["String"]
11-
elseif b.val.arg2.kind == CSTParser.Tokenize.Tokens.INTEGER
12-
b.t = server.packages["Core"].vals["Int"]
13-
elseif b.val.arg2.kind == CSTParser.Tokenize.Tokens.FLOAT
14-
b.t = server.packages["Core"].vals["Float64"]
15-
elseif b.val.arg2.kind == CSTParser.Tokenize.Tokens.HEX_INT || b.val.arg2.kind == CSTParser.Tokenize.Tokens.OCT_INT || b.val.arg2.kind == CSTParser.Tokenize.Tokens.BIN_INT
16-
b.t = server.packages["Core"].vals["UInt64"]
17-
elseif b.val.arg2.kind == CSTParser.Tokenize.Tokens.CHAR
18-
b.t = server.packages["Core"].vals["Char"]
19-
end
34+
b.t = infer_literal(b.val.arg2, server)
2035
elseif b.val.arg2 isa CSTParser.IDENTIFIER
2136
# rhs is an ID, copy typing from that reference
2237
offset = b.loc.offset + b.val.arg1.fullspan + b.val.op.fullspan
2338
rhs_ref = find_ref(rrefs, offset, b.loc.file)
24-
if rhs_ref.b isa ImportBinding
39+
if rhs_ref == nothing
40+
elseif rhs_ref.b isa ImportBinding
2541
b.t = rhs_ref.b.val
26-
elseif rhs_ref != nothing
42+
else
2743
if rhs_ref.b.t == nothing
2844
infer(rhs_ref.b, server, rrefs)
2945
end
@@ -33,7 +49,8 @@ function infer(b, server, rrefs)
3349
elseif b.val.arg2 isa CSTParser.EXPR{CSTParser.Call}
3450
offset = b.loc.offset + b.val.arg1.fullspan + b.val.op.fullspan
3551
rhs_ref = find_ref(rrefs, offset, b.loc.file)
36-
if rhs_ref.b isa ImportBinding
52+
if rhs_ref == nothing
53+
elseif rhs_ref.b isa ImportBinding
3754
if rhs_ref.b.val isa SymbolServer.structStore || rhs_ref.b.val isa SymbolServer.abstractStore || rhs_ref.b.val isa SymbolServer.primitiveStore
3855
b.t = rhs_ref.b.val
3956
end
@@ -42,4 +59,5 @@ function infer(b, server, rrefs)
4259
end
4360
end
4461
end
45-
end
62+
end
63+

src/utils.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ function get_include(x, state, s)
202202
end
203203
push!(state.includes, Include(file, path, state.loc.offset, s.index, s.bindings))
204204
s.bindings = file.scope.bindings
205+
else
206+
push!(state.linterrors, LintError(IncludeFail, deepcopy(state.loc), x))
205207
end
206208
end
207209
end

0 commit comments

Comments
 (0)