1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2012 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Simple vavious processing on a AST
18 # The analysis warns on :
19 # * superfluous parentheses
20 # * nested "once" expressions
21 # * use of "while true" instead of "loop"
22 module simple_misc_analysis
26 redef class ToolContext
27 # Execute `AModule::do_simple_misc_analysis` on each module.
28 var simple_misc_analysis_phase
: Phase = new SimpleMiscAnalysisPhase(self, null)
31 private class SimpleMiscAnalysisPhase
33 redef fun process_nmodule
(nmodule
) do nmodule
.do_simple_misc_analysis
(toolcontext
)
37 # Visit the module to detect easy warnings that does not need the metamodel or the importation
38 # Warnings are displayed on the toolcontext
39 fun do_simple_misc_analysis
(toolcontext
: ToolContext)
41 var v
= new SimpleMiscVisitor(toolcontext
)
44 var t
= location
.file
.first_token
46 t
.accept_simple_misc_token
(v
)
52 private class SimpleMiscVisitor
56 n
.accept_simple_misc
(self)
59 # Number of nested once
60 var once_count
: Int = 0
62 var toolcontext
: ToolContext
64 fun warning
(node
: ANode, tag
, msg
: String)
66 toolcontext
.warning
(node
.hot_location
, tag
, msg
)
69 # Issue a warning if `sub` is a standalone `do` block.
70 fun check_do_expr
(sub
: nullable AExpr)
72 if sub
isa ADoExpr then
73 warning
(sub
, "useless-do", "Warning: superfluous `do` block.")
79 ###############################################################################
82 private fun accept_simple_misc
(v
: SimpleMiscVisitor)
87 private fun after_simple_misc
(v
: SimpleMiscVisitor) do end
91 private fun accept_simple_misc_token
(v
: SimpleMiscVisitor)
96 redef class ASignature
97 redef fun after_simple_misc
(v
)
99 if self.n_opar
!= null and self.n_params
.is_empty
then
100 v
.warning
(self, "parentheses", "Warning: superfluous parentheses.")
106 # Warn in case of superfluous parentheses
107 private fun warn_parentheses
(v
: SimpleMiscVisitor) do end
111 redef fun warn_parentheses
(v
)
113 v
.warning
(self, "parentheses", "Warning: superfluous parentheses.")
117 redef class AParExprs
118 redef fun after_simple_misc
(v
)
120 if n_exprs
.is_empty
then
121 v
.warning
(self, "parentheses", "Warning: superfluous parentheses.")
126 redef class AReturnExpr
127 redef fun after_simple_misc
(v
)
131 e
.warn_parentheses
(v
)
136 redef class AEscapeExpr
137 redef fun after_simple_misc
(v
)
141 e
.warn_parentheses
(v
)
146 redef class AWhileExpr
147 redef fun after_simple_misc
(v
)
149 if n_expr
isa ATrueExpr then
150 v
.warning
(self, "loop", "Warning: use `loop` instead of `while true do`.")
152 n_expr
.warn_parentheses
(v
)
154 v
.check_do_expr
(n_block
)
159 redef fun after_simple_misc
(v
)
161 v
.check_do_expr
(n_block
)
165 redef class ALoopExpr
166 redef fun after_simple_misc
(v
)
168 v
.check_do_expr
(n_block
)
173 redef fun after_simple_misc
(v
)
175 n_expr
.warn_parentheses
(v
)
176 v
.check_do_expr
(n_block
)
180 redef class AWithExpr
181 redef fun after_simple_misc
(v
)
183 v
.check_do_expr
(n_block
)
188 redef fun after_simple_misc
(v
)
190 n_expr
.warn_parentheses
(v
)
194 redef class AIfexprExpr
195 redef fun after_simple_misc
(v
)
197 n_expr
.warn_parentheses
(v
)
201 redef class AOnceExpr
202 redef fun accept_simple_misc
(v
)
204 if v
.once_count
> 0 then
205 v
.warning
(self, "nested-once", "Warning: useless once in a once expression.")
207 v
.once_count
= v
.once_count
+ 1
211 v
.once_count
= v
.once_count
- 1
216 redef fun accept_simple_misc_token
(v
)
231 v
.warning
(self, "semi", "Warning: superfluous `;`.")