The analysis warns on :
nitc :: simple_misc_analysis $ AForGroup
A collection iterated by a for, its automatic variables and its implicit iterator.nitc :: simple_misc_analysis $ AIfexprExpr
Aif
expression (ternary conditional). eg. if true then 1 else 0
nitc :: simple_misc_analysis $ AParExprs
A list of expressions enclosed in parenthesesnitc :: simple_misc_analysis $ ASignature
A signature in a method definition. eg(x,y:X,z:Z):T
nitc :: simple_misc_analysis $ AForGroup
A collection iterated by a for, its automatic variables and its implicit iterator.nitc :: simple_misc_analysis $ AIfexprExpr
Aif
expression (ternary conditional). eg. if true then 1 else 0
nitc :: simple_misc_analysis $ AParExprs
A list of expressions enclosed in parenthesesnitc :: simple_misc_analysis $ ASignature
A signature in a method definition. eg(x,y:X,z:Z):T
Serializable::inspect
to show more useful information
more_collections :: more_collections
Highly specific, but useful, collections-related classes.serialization :: serialization_core
Abstract services to serialize Nit objects to different formatsnitc :: toolcontext
Common command-line tool infrastructure than handle options and error messagescore :: union_find
union–find algorithm using an efficient disjoint-set data structurenitc :: api_metrics
nitc :: nitmetrics
A program that collects various metrics on nit programs and librariesnitc :: nitrestful
Tool generating boilerplate code linking RESTful actions to Nit methodsclone
method of the astbuilder tool
# Simple vavious processing on a AST
# The analysis warns on :
# * superfluous parentheses
# * nested "once" expressions
# * use of "while true" instead of "loop"
module simple_misc_analysis
import phase
redef class ToolContext
# Execute `AModule::do_simple_misc_analysis` on each module.
var simple_misc_analysis_phase: Phase = new SimpleMiscAnalysisPhase(self, null)
end
private class SimpleMiscAnalysisPhase
super Phase
redef fun process_nmodule(nmodule) do nmodule.do_simple_misc_analysis(toolcontext)
end
redef class AModule
# Visit the module to detect easy warnings that does not need the metamodel or the importation
# Warnings are displayed on the toolcontext
fun do_simple_misc_analysis(toolcontext: ToolContext)
do
var v = new SimpleMiscVisitor(toolcontext)
v.enter_visit(self)
var t = location.file.first_token
while t != null do
t.accept_simple_misc_token(v)
t = t.next_token
end
end
end
private class SimpleMiscVisitor
super Visitor
redef fun visit(n)
do
n.accept_simple_misc(self)
end
# Number of nested once
var once_count: Int = 0
var toolcontext: ToolContext
fun warning(node: ANode, tag, msg: String)
do
toolcontext.warning(node.hot_location, tag, msg)
end
# Issue a warning if `sub` is a standalone `do` block.
fun check_do_expr(sub: nullable AExpr)
do
if sub isa ADoExpr then
warning(sub, "useless-do", "Warning: superfluous `do` block.")
end
end
end
###############################################################################
redef class ANode
private fun accept_simple_misc(v: SimpleMiscVisitor)
do
visit_all(v)
after_simple_misc(v)
end
private fun after_simple_misc(v: SimpleMiscVisitor) do end
end
redef class Token
private fun accept_simple_misc_token(v: SimpleMiscVisitor)
do
end
end
redef class ASignature
redef fun after_simple_misc(v)
do
if self.n_opar != null and self.n_params.is_empty then
v.warning(self, "parentheses", "Warning: superfluous parentheses.")
end
end
end
redef class AExpr
# Warn in case of superfluous parentheses
private fun warn_parentheses(v: SimpleMiscVisitor) do end
end
redef class AParExpr
redef fun warn_parentheses(v)
do
v.warning(self, "parentheses", "Warning: superfluous parentheses.")
end
end
redef class AParExprs
redef fun after_simple_misc(v)
do
if n_exprs.is_empty then
v.warning(self, "parentheses", "Warning: superfluous parentheses.")
end
end
end
redef class AReturnExpr
redef fun after_simple_misc(v)
do
var e = n_expr
if e != null then
e.warn_parentheses(v)
end
end
end
redef class AEscapeExpr
redef fun after_simple_misc(v)
do
var e = n_expr
if e != null then
e.warn_parentheses(v)
end
end
end
redef class AWhileExpr
redef fun after_simple_misc(v)
do
if n_expr isa ATrueExpr then
v.warning(self, "loop", "Warning: use `loop` instead of `while true do`.")
else
n_expr.warn_parentheses(v)
end
v.check_do_expr(n_block)
end
end
redef class ADoExpr
redef fun after_simple_misc(v)
do
v.check_do_expr(n_block)
end
end
redef class ALoopExpr
redef fun after_simple_misc(v)
do
v.check_do_expr(n_block)
end
end
redef class AForExpr
redef fun after_simple_misc(v)
do
v.check_do_expr(n_block)
end
end
redef class AForGroup
redef fun after_simple_misc(v)
do
n_expr.warn_parentheses(v)
end
end
redef class AWithExpr
redef fun after_simple_misc(v)
do
v.check_do_expr(n_block)
end
end
redef class AIfExpr
redef fun after_simple_misc(v)
do
n_expr.warn_parentheses(v)
end
end
redef class AIfexprExpr
redef fun after_simple_misc(v)
do
n_expr.warn_parentheses(v)
end
end
redef class AOnceExpr
redef fun accept_simple_misc(v)
do
if v.once_count > 0 then
v.warning(self, "nested-once", "Warning: useless once in a once expression.")
end
v.once_count = v.once_count + 1
super
v.once_count = v.once_count - 1
end
end
redef class TSemi
redef fun accept_simple_misc_token(v)
do
var n = next_token
var p = prev_token
if
n == null or
n isa TEol or
n isa EOF or
n isa TComment or
p == null or
p isa TEol or
p isa EOF or
p isa TComment or
p isa TSemi
then
v.warning(self, "semi", "Warning: superfluous `;`.")
return
end
end
end
src/frontend/simple_misc_analysis.nit:17,1--241,3