contrib/objcwrapper: each ObjcProperty keeps track of its declaring class
[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 c = v.objc_class
77 assert c != null
78
79 var method = new ObjcMethod(c)
80 method.return_type = n_signature_return_type.to_type
81 method.is_class_property = n_scope.is_class_property
82
83 for n_param in n_parameter.children do
84 var param = n_param.to_param
85 if param == null then
86
87 # Unsupported parameter format
88 method.is_commented = true
89
90 # Use a placeholder for easier debugging
91 param = new ObjcParam
92 param.name = "UNKNOWN"
93 param.return_type = "UNKNOWN"
94 param.variable_name = "UNKNOWN"
95 end
96
97 method.params.add param
98 end
99
100 c.methods.add method
101 end
102 end
103
104 # Class variable/attribute declaration (inside alternative node)
105 redef class Nproperty_property
106 redef fun accept_objc(v)
107 do
108 var c = v.objc_class
109 assert c != null
110
111 var attr = new ObjcAttribute(c)
112 attr.return_type = n_type.to_type
113 attr.name = n_left.collect_text
114
115 c.attributes.add attr
116 end
117 end
118
119 # Class variable/attribute declaration (outside with @property)
120 redef class Nproperty_declaration_property
121 redef fun accept_objc(v)
122 do
123 # TODO property attribute readonly, copy, etc.
124 super
125 end
126 end
127
128 # ---
129 # Support nodes
130
131 redef class NProd
132 # Append all tokens under this node in a `String`
133 private fun collect_text: String
134 do
135 var buf = new FlatBuffer
136 for node in depth do if node isa NToken then buf.append node.text
137 return buf.to_s
138 end
139 end
140
141 redef class Nlines
142 # Do not visit other lines, they are only to be eaten
143 redef fun accept_objc(v) do end
144 end
145
146 redef class Nscope
147 # Does this mark a class property (+)? Otherwise it's an instance property (-).
148 private fun is_class_property: Bool do return false
149 end
150
151 redef class Nscope_class
152 redef fun is_class_property do return true
153 end
154
155 redef class Nsignature_return_type
156 # Get type from this node TODO return an ObjcType
157 private fun to_type: String do return collect_text
158 end
159
160 redef class Nsignature_return_type_return
161 redef fun to_type do return n_type.to_type
162 end
163
164 redef class Nparameter
165 # Return null if type is not yet unsupported
166 private fun to_param: nullable ObjcParam do return null
167 end
168
169 # Parameters with both a public and an internal name
170 redef class Nparameter_named
171 redef fun to_param
172 do
173 var param = new ObjcParam
174 param.variable_name = n_right.collect_text
175 param.name = n_left.collect_text
176
177 var n_type = n_parameter_type_in_par
178 param.return_type = if n_type != null then
179 n_type.n_parameter_type.to_type
180 else "NSObject"
181
182 return param
183 end
184 end
185
186 # Usually the name of a method without parameters
187 redef class Nparameter_single
188 redef fun to_param
189 do
190 var param = new ObjcParam
191 param.name = n_term.collect_text
192 param.is_single = true
193 return param
194 end
195 end
196
197 redef class Nparameter_type
198 # Get type from this node TODO return an ObjcType
199 private fun to_type: String
200 do
201 # FIXME taking the first token skips pointers
202 for child in children do
203 if child isa Ntype then
204 return child.to_type
205 end
206 end
207
208 return collect_text
209 end
210 end
211
212 redef class Ntype
213 # Get type from this node TODO return an ObjcType
214 private fun to_type: String do return collect_text
215 end