model: new metamodel
[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
27 redef class AModule
28 # Visit the module to detect easy warnings that does not need the metamodel or the importation
29 # Warnings are displayed on the toolcontext
30 fun do_simple_misc_analysis(toolcontext: ToolContext)
31 do
32 var v = new SimpleMiscVisitor(toolcontext)
33 v.enter_visit(self)
34 end
35 end
36
37 private class SimpleMiscVisitor
38 super Visitor
39 redef fun visit(n)
40 do
41 if n != null then n.accept_simple_misc(self)
42 end
43
44 # Number of nested once
45 var once_count: Int = 0
46
47 var toolcontext: ToolContext
48
49 fun warning(node: ANode, msg: String)
50 do
51 toolcontext.warning(node.hot_location, msg)
52 end
53
54 init(toolcontext: ToolContext)
55 do
56 self.toolcontext = toolcontext
57 end
58 end
59
60
61 ###############################################################################
62
63 redef class ANode
64 private fun accept_simple_misc(v: SimpleMiscVisitor)
65 do
66 visit_all(v)
67 after_simple_misc(v)
68 end
69 private fun after_simple_misc(v: SimpleMiscVisitor) do end
70 end
71
72 redef class ASignature
73 redef fun after_simple_misc(v)
74 do
75 if self.n_opar != null and self.n_params.is_empty then
76 v.warning(self, "Warning: superfluous parentheses.")
77 end
78 end
79 end
80
81 redef class AExpr
82 # Warn in case of superfluous parentheses
83 private fun warn_parentheses(v: SimpleMiscVisitor) do end
84 end
85
86 redef class AParExpr
87 redef fun warn_parentheses(v)
88 do
89 v.warning(self, "Warning: superfluous parentheses.")
90 end
91 end
92
93 redef class AParExprs
94 redef fun after_simple_misc(v)
95 do
96 if n_exprs.is_empty then
97 v.warning(self, "Warning: superfluous parentheses.")
98 end
99 end
100 end
101
102 redef class AReturnExpr
103 redef fun after_simple_misc(v)
104 do
105 var e = n_expr
106 if e != null then
107 e.warn_parentheses(v)
108 end
109 end
110 end
111
112 redef class AContinueExpr
113 redef fun after_simple_misc(v)
114 do
115 var e = n_expr
116 if e != null then
117 e.warn_parentheses(v)
118 end
119 end
120 end
121
122 redef class ABreakExpr
123 redef fun after_simple_misc(v)
124 do
125 var e = n_expr
126 if e != null then
127 e.warn_parentheses(v)
128 end
129 end
130 end
131
132 redef class AWhileExpr
133 redef fun after_simple_misc(v)
134 do
135 if n_expr isa ATrueExpr then
136 v.warning(self, "Warning: use 'loop' instead of 'while true do'.")
137 else
138 n_expr.warn_parentheses(v)
139 end
140 end
141 end
142
143 redef class AForExpr
144 redef fun after_simple_misc(v)
145 do
146 n_expr.warn_parentheses(v)
147 end
148 end
149
150 redef class AIfExpr
151 redef fun after_simple_misc(v)
152 do
153 n_expr.warn_parentheses(v)
154 end
155 end
156
157 redef class AIfexprExpr
158 redef fun after_simple_misc(v)
159 do
160 n_expr.warn_parentheses(v)
161 end
162 end
163
164 redef class AOnceExpr
165 redef fun accept_simple_misc(v)
166 do
167 if v.once_count > 0 then
168 v.warning(self, "Useless once in a once expression.")
169 end
170 v.once_count = v.once_count + 1
171
172 super
173
174 v.once_count = v.once_count - 1
175 end
176 end