Syntax Reference
StaticLint.Binding
StaticLint.BoundAfter
StaticLint.ComesBefore
StaticLint.ExternalEnv
StaticLint.add_binding
StaticLint.addmoduletoscope!
StaticLint.check_kw_default
StaticLint.check_parent_scopes_for
StaticLint.collect_hints
StaticLint.eventually_overloads
StaticLint.followinclude
StaticLint.get_parent_fexpr
StaticLint.get_path
StaticLint.getenv
StaticLint.interpret_eval
StaticLint.introduces_scope
StaticLint.is_in_fexpr
StaticLint.lint_file
StaticLint.lint_string
StaticLint.mark_bindings!
StaticLint.maybe_quoted_list
StaticLint.new_within_struct
StaticLint.resolve_getfield
StaticLint.scope_exports
StaticLint.scopehasbinding
StaticLint.scopehasmodule
StaticLint.scopes
StaticLint.semantic_pass
StaticLint.traverse
StaticLint.valofid
Main
StaticLint.ExternalEnv
— TypeExternalEnv
Holds a representation of an environment cached by SymbolServer.
StaticLint.followinclude
— Methodfollowinclude(x, state)
Checks whether the arguments of a call to include
can be resolved to a path. If successful it checks whether a file with that path is loaded on the server or a file exists on the disc that can be loaded. If this is successful it traverses the code associated with the loaded file.
StaticLint.get_path
— Methodget_path(x::EXPR)
Usually called on the argument to include
calls, and attempts to determine the path of the file to be included. Has limited support for joinpath
calls.
StaticLint.semantic_pass
— Functionsemantic_pass(file, modified_expr=nothing)
Performs a semantic pass across a project from the entry point file
. A first pass traverses the top-level scope after which secondary passes handle delayed scopes (e.g. functions). These secondary passes can be, optionally, very light and only seek to resovle references (e.g. link symbols to bindings). This can be done by supplying a list of expressions on which the full secondary pass should be made (modified_expr
), all others will receive the light-touch version.
StaticLint.traverse
— Methodtraverse(x, state)
Iterates across the child nodes of an EXPR in execution order (rather than storage order) calling state
on each node.
StaticLint.Binding
— TypeBindings indicate that an EXPR
may introduce a new name into the current scope/namespace. Struct fields:
name
: theEXPR
that defines the unqualifed name of the binding.val
: what the binding points to, either aBinding
(indicating ..),EXPR
(this is generally the expression that defines the value) orSymStore
.type
: the type of the binding, either aBinding
,EXPR
, orSymStore
.refs
: a list containing all references that have been made to the binding.
StaticLint.add_binding
— Functionadd_binding(x, state, scope=state.scope)
Add the binding of x
to the current scope. Special handling is required for:
- macros: to prefix the
@
- functions: These are added to the top-level scope unless this syntax is used to define a closure within a function. If a function with the same name already exists in the scope then it is not replaced. This enables the
refs
list of the Binding of that 'root method' to hold a method table, the name of the new function will resolve to the binding of the root method (to get a list of actual methods -[get_method(ref) for ref in binding.refs if get_method(ref) !== nothing]
). For example
[1] f() = 1
[2] f(x) = 2
[1] is the root method and the name of [2] resolves to the binding of [1]. Functions declared with qualified names require special handling, there are comments in the source.
Some simple type inference is run.
StaticLint.eventually_overloads
— Methodeventually_overloads(b, x, state)
StaticLint.mark_bindings!
— Methodmark_bindings!(x::EXPR, state)
Checks whether the expression x
should introduce new names and marks them as needed. Generally this marks expressions that would introdce names to the current scope (i.e. that x sits in) but in cases marks expressions that will add names to lower scopes. This is done when it is not knowable that a child node of x
will introduce a new name without the context of where it sits in x
-for example the arguments of the signature of a function definition.
StaticLint.lint_file
— Functionlint_file(rootpath, server)
Read a file from disc, parse and run a semantic pass over it. The file should be the root of a project, e.g. for this package that file is src/StaticLint.jl
. Other files in the project will be loaded automatically (calls to include
with complicated arguments are not handled, see followinclude
for details). A FileServer
will be returned containing the File
s of the package.
StaticLint.lint_string
— Functionlint_string(s, server; gethints = false)
Parse a string and run a semantic pass over it. This will mark scopes, bindings, references, and lint hints. An annotated EXPR
is returned or, if gethints = true
, it is paired with a collected list of errors/hints.
StaticLint.interpret_eval
— Methodinterpret_eval(x::EXPR, state)
Naive attempt to interpret x
as though it has been eval'ed. Lifts any bindings made within the scope of x
to the toplevel and replaces (some) interpolated binding names with the value where possible.
StaticLint.maybe_quoted_list
— Methodmaybe_quoted_list(x::EXPR)
Try and get a list of quoted symbols from x. Return nothing if not possible.
StaticLint.new_within_struct
— Methodnewwithinstruct(x::EXPR)
Checks whether x is a reference to new
within a datatype constructor.
StaticLint.resolve_getfield
— Methodresolve_getfield(x::EXPR, parent::Union{EXPR,Scope,ModuleStore,Binding}, state::State)::Bool
Given an expression of the form parent.x
try to resolve x
. The method called with parent::EXPR
resolves the reference for parent
, other methods then check whether the Binding/Scope/ModuleStore to which parent
points has a field matching x
.
StaticLint.scope_exports
— Methodscope_exports(scope::Scope, name::String)
Does the scope export a variable called name
?
StaticLint.valofid
— Methodvalofid(x)
Returns the string value of an expression for which isidentifier
is true, i.e. handles NONSTDIDENTIFIERs.
StaticLint.addmoduletoscope!
— Methodaddmoduletoscope!(s, m, [mname::Symbol])
Adds module m
to the list of used modules in scope s
.
StaticLint.introduces_scope
— Methodintroduces_scope(x::EXPR, state)
Does this expression introduce a new scope?
StaticLint.scopehasbinding
— Methodscopehasbinding(s::Scope, n::String)
Checks whether s has a binding for variable named n
.
StaticLint.scopehasmodule
— Methodscopehasmodule(s::Scope, mname::Symbol)::Bool
Checks whether the module mname
has been using
ed in s
.
StaticLint.scopes
— Methodscopes(x::EXPR, state)
Called when traversing the syntax tree and handles the association of scopes with expressions. On the first pass this will add scopes as necessary, on following passes it empties it.
StaticLint.getenv
— Methodgetenv(file::File, server::FileServer)
Get the relevant ExternalEnv
for a given file.
StaticLint.get_parent_fexpr
— Methodget_in_fexpr(x::EXPR, f)
Get the parent
of x
for which f(parent) == true
. (isinfexpr should be called first.)
StaticLint.is_in_fexpr
— Methodis_in_fexpr(x::EXPR, f)
Check whether x
isa the child of an expression for which f(parent) == true
.
Linting
StaticLint.BoundAfter
— TypeComesBefore
Check whether x1 comes before x2
StaticLint.ComesBefore
— TypeComesBefore
Check whether x1 comes before x2
StaticLint.check_kw_default
— Methodcheck_kw_default(x::EXPR, server)
Check that the default value matches the type for keyword arguments. Following types are checked: String, Symbol, Int, Char, Bool, Float32, Float64, UInt8, UInt16, UInt32, UInt64, UInt128
.
StaticLint.check_parent_scopes_for
— Methodcheck_parent_scopes_for(s::Scope, name)
Checks whether the parent scope of s
has the name name
.
StaticLint.collect_hints
— Functioncollect_hints(x::EXPR, env, missingrefs = :all, isquoted = false, errs = Tuple{Int,EXPR}[], pos = 0)
Collect hints and errors from an expression. missingrefs
= (:none, :id, :all) determines whether unresolved identifiers are marked, the :all option will mark identifiers used in getfield calls."