contrib/objcwrapper: revamp the AST visitor
[nit.git] / contrib / objcwrapper / src / objc_visitor.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # AST visitor
16 module objc_visitor
17
18 import objc_model
19 import objc_parser
20
21 # AST visitor building `model` from the parsed class headers
22 class ObjcVisitor
23 super Visitor
24
25 # `ObjcModel` in construction
26 var model = new ObjcModel
27
28 # `ObjcClass` in construction, if any
29 private var objc_class: nullable ObjcClass = null
30
31 redef fun visit(n) do n.accept_objc(self)
32 end
33
34 redef class Node
35 private fun accept_objc(v: ObjcVisitor) do visit_children(v)
36 end
37
38 # ---
39 # Main nodes
40
41 # Class declaration
42 redef class Nlines_interface
43 redef fun accept_objc(v)
44 do
45 var interface_block = n_interface_block
46 if interface_block == null then return
47
48 # If reopening a class, continue with the exisitng one
49 var c = null
50 for objc_class in v.model.classes do
51 if objc_class.name == n_class.text then
52 c = objc_class
53 end
54 end
55
56 # New class
57 if c == null then
58 c = new ObjcClass(n_class.text)
59 v.model.classes.add c
60 end
61 v.objc_class = c
62
63 # Visit superclass declarations
64 var inheritance_block = n_inheritance
65 if inheritance_block != null then v.enter_visit(inheritance_block)
66
67 # Visit main body
68 v.enter_visit(interface_block)
69 end
70 end
71
72 # Method or function declaration
73 redef class Nsignature_block_signature
74 redef fun accept_objc(v)
75 do
76 var method = new ObjcMethod
77 method.return_type = n_signature_return_type.to_type
78 method.scope = if n_scope.is_class_property then '-' else '+'
79
80 for n_param in n_parameter.children do
81 var param = n_param.to_param
82 if param == null then
83
84 # Unsupported parameter format
85 method.is_commented = true
86
87 # Use a placeholder for easier debugging
88 param = new Param
89 param.name = "UNKNOWN"
90 param.return_type = "UNKNOWN"
91 param.variable_name = "UNKNOWN"
92 end
93
94 method.params.add param
95 end
96
97 v.objc_class.methods.add method
98 end
99 end
100
101 # Class variable/attribute declaration (inside alternative node)
102 redef class Nproperty_property
103 redef fun accept_objc(v)
104 do
105 var attr = new ObjcAttribute
106 attr.return_type = n_type.to_type
107 attr.name = n_left.collect_text
108
109 v.objc_class.attributes.add attr
110 end
111 end
112
113 # Class variable/attribute declaration (outside with @property)
114 redef class Nproperty_declaration_property
115 redef fun accept_objc(v)
116 do
117 # TODO property attribute readonly, copy, etc.
118 super
119 end
120 end
121
122 # ---
123 # Support nodes
124
125 redef class NProd
126 # Append all tokens under this node in a `String`
127 private fun collect_text: String
128 do
129 var buf = new FlatBuffer
130 for node in depth do if node isa NToken then buf.append node.text
131 return buf.to_s
132 end
133 end
134
135 redef class Nlines
136 # Do not visit other lines, they are only to be eaten
137 redef fun accept_objc(v) do end
138 end
139
140 redef class Nscope
141 # Does this mark a class property (+)? Otherwise it's an instance property (-).
142 private fun is_class_property: Bool do return false
143 end
144
145 redef class Nscope_class
146 redef fun is_class_property do return true
147 end
148
149 redef class Nsignature_return_type
150 # Get type from this node TODO return an ObjcType
151 private fun to_type: String do return collect_text
152 end
153
154 redef class Nsignature_return_type_return
155 redef fun to_type do return n_type.to_type
156 end
157
158 redef class Nparameter
159 # Return null if type is not yet unsupported
160 private fun to_param: nullable Param do return null
161 end
162
163 # Parameters with both a public and an internal name
164 redef class Nparameter_named
165 redef fun to_param
166 do
167 var param = new Param
168 param.variable_name = n_right.collect_text
169 param.name = n_left.collect_text
170 param.return_type = n_parameter_type.to_type
171 return param
172 end
173 end
174
175 # Usually the name of a method without parameters
176 redef class Nparameter_single
177 redef fun to_param
178 do
179 var param = new Param
180 param.name = n_term.collect_text
181 param.is_single = true
182 return param
183 end
184 end
185
186 redef class Nparameter_type
187 # Get type from this node TODO return an ObjcType
188 private fun to_type: String
189 do
190 # FIXME taking the first token skips pointers
191 for child in children do
192 if child isa Ntype then
193 return child.to_type
194 end
195 end
196
197 return collect_text
198 end
199 end
200
201 redef class Ntype
202 # Get type from this node TODO return an ObjcType
203 private fun to_type: String do return collect_text
204 end