ni_nitdoc: added fast copy past utility to signatures.
[nit.git] / src / simple_misc_analysis.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Jean Privat <jean@pryen.org>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
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 package simple_misc_analysis
23
24 import toolcontext
25 import parser
26 import phase
27
28 import modelbuilder #FIXME useless
29
30 redef class ToolContext
31 var simple_misc_analysis_phase: Phase = new SimpleMiscAnalysisPhase(self, null)
32 end
33
34 private class SimpleMiscAnalysisPhase
35 super Phase
36 redef fun process_nmodule(nmodule) do nmodule.do_simple_misc_analysis(toolcontext)
37 end
38
39 redef class AModule
40 # Visit the module to detect easy warnings that does not need the metamodel or the importation
41 # Warnings are displayed on the toolcontext
42 fun do_simple_misc_analysis(toolcontext: ToolContext)
43 do
44 var v = new SimpleMiscVisitor(toolcontext)
45 v.enter_visit(self)
46 end
47 end
48
49 private class SimpleMiscVisitor
50 super Visitor
51 redef fun visit(n)
52 do
53 if n != null then n.accept_simple_misc(self)
54 end
55
56 # Number of nested once
57 var once_count: Int = 0
58
59 var toolcontext: ToolContext
60
61 fun warning(node: ANode, msg: String)
62 do
63 toolcontext.warning(node.hot_location, msg)
64 end
65
66 init(toolcontext: ToolContext)
67 do
68 self.toolcontext = toolcontext
69 end
70 end
71
72
73 ###############################################################################
74
75 redef class ANode
76 private fun accept_simple_misc(v: SimpleMiscVisitor)
77 do
78 visit_all(v)
79 after_simple_misc(v)
80 end
81 private fun after_simple_misc(v: SimpleMiscVisitor) do end
82 end
83
84 redef class ASignature
85 redef fun after_simple_misc(v)
86 do
87 if self.n_opar != null and self.n_params.is_empty then
88 v.warning(self, "Warning: superfluous parentheses.")
89 end
90 end
91 end
92
93 redef class AExpr
94 # Warn in case of superfluous parentheses
95 private fun warn_parentheses(v: SimpleMiscVisitor) do end
96 end
97
98 redef class AParExpr
99 redef fun warn_parentheses(v)
100 do
101 v.warning(self, "Warning: superfluous parentheses.")
102 end
103 end
104
105 redef class AParExprs
106 redef fun after_simple_misc(v)
107 do
108 if n_exprs.is_empty then
109 v.warning(self, "Warning: superfluous parentheses.")
110 end
111 end
112 end
113
114 redef class AReturnExpr
115 redef fun after_simple_misc(v)
116 do
117 var e = n_expr
118 if e != null then
119 e.warn_parentheses(v)
120 end
121 end
122 end
123
124 redef class AContinueExpr
125 redef fun after_simple_misc(v)
126 do
127 var e = n_expr
128 if e != null then
129 e.warn_parentheses(v)
130 end
131 end
132 end
133
134 redef class ABreakExpr
135 redef fun after_simple_misc(v)
136 do
137 var e = n_expr
138 if e != null then
139 e.warn_parentheses(v)
140 end
141 end
142 end
143
144 redef class AWhileExpr
145 redef fun after_simple_misc(v)
146 do
147 if n_expr isa ATrueExpr then
148 v.warning(self, "Warning: use 'loop' instead of 'while true do'.")
149 else
150 n_expr.warn_parentheses(v)
151 end
152 end
153 end
154
155 redef class AForExpr
156 redef fun after_simple_misc(v)
157 do
158 n_expr.warn_parentheses(v)
159 end
160 end
161
162 redef class AIfExpr
163 redef fun after_simple_misc(v)
164 do
165 n_expr.warn_parentheses(v)
166 end
167 end
168
169 redef class AIfexprExpr
170 redef fun after_simple_misc(v)
171 do
172 n_expr.warn_parentheses(v)
173 end
174 end
175
176 redef class AOnceExpr
177 redef fun accept_simple_misc(v)
178 do
179 if v.once_count > 0 then
180 v.warning(self, "Useless once in a once expression.")
181 end
182 v.once_count = v.once_count + 1
183
184 super
185
186 v.once_count = v.once_count - 1
187 end
188 end