1 /***
2 * Cecilia ADL Compiler
3 * Copyright (C) 2006-2007 STMicroelectronics
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Contact: fractal@objectweb.org
20 *
21 * Author: Matthieu Leclercq
22 * Contributor: Alessio Pace
23 */
24
25 package org.objectweb.fractal.cecilia.adl.idl.util;
26
27 import org.objectweb.fractal.adl.Node;
28 import org.objectweb.fractal.cecilia.adl.idl.ast.ArrayOf;
29 import org.objectweb.fractal.cecilia.adl.idl.ast.ComplexType;
30 import org.objectweb.fractal.cecilia.adl.idl.ast.Field;
31 import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinition;
32 import org.objectweb.fractal.cecilia.adl.idl.ast.Import;
33 import org.objectweb.fractal.cecilia.adl.idl.ast.Method;
34 import org.objectweb.fractal.cecilia.adl.idl.ast.MethodContainer;
35 import org.objectweb.fractal.cecilia.adl.idl.ast.Parameter;
36 import org.objectweb.fractal.cecilia.adl.idl.ast.PointerOf;
37 import org.objectweb.fractal.cecilia.adl.idl.ast.PrimitiveType;
38 import org.objectweb.fractal.cecilia.adl.idl.ast.Type;
39 import org.objectweb.fractal.cecilia.adl.idl.ast.TypeContainer;
40 import org.objectweb.fractal.cecilia.adl.idl.ast.PrimitiveType.PrimitiveTypeEnum;
41
42 /**
43 * Provides utility methods to manipulate IDL AST nodes.
44 */
45 public final class Util {
46
47 private Util() {
48 }
49
50 // ---------------------------------------------------------------------------
51 // Type utility methods
52 // ---------------------------------------------------------------------------
53
54 /**
55 * Returns <code>true</code> if the given type node is a complex type or
56 * either an array or pointer of complex type.
57 *
58 * @param type a type node.
59 * @return <code>true</code> if the given type node is a complex type or
60 * either an array or pointer of complex type.
61 */
62 public static boolean isComplexType(final Type type) {
63 if (type instanceof ComplexType) {
64 return true;
65 } else if ((type instanceof ArrayOf) || (type instanceof PointerOf)) {
66 return isComplexType(getContainedType((TypeContainer) type));
67 } else {
68 return false;
69 }
70 }
71
72 /**
73 * @param type
74 * @return <code>true</code> is the given type node is a
75 * {@link PrimitiveType}, <code>false</code> otherwise.
76 */
77 public static boolean isPrimitiveType(final Type type) {
78 if (type instanceof PrimitiveType) {
79 return true;
80 }
81 return false;
82
83 }
84
85 /**
86 * Returns the complex type node contained by the given type. More precisely,
87 * if the given <code>type</code> is a {@link ComplexType} this method
88 * simply return it; if the given <code>type</code> is an {@link ArrayOf} of
89 * a {@link PointerOf}, returns the complex type it contains; else, throws an
90 * {@link IllegalArgumentException}
91 *
92 * @param type a {@link ComplexType} or a container of {@link ComplexType}
93 * @return the complex type node contained by the given type.
94 * @throws IllegalArgumentException if
95 * <code>{@link #isComplexType(Type)}(type)</code> is
96 * <code>false</code>.
97 */
98 public static ComplexType getComplexType(final Type type) {
99 if (type instanceof ComplexType) {
100 return (ComplexType) type;
101 } else if ((type instanceof ArrayOf) || (type instanceof PointerOf)) {
102 return getComplexType(getContainedType((TypeContainer) type));
103 } else {
104 throw new IllegalArgumentException(
105 "The given type is not a complex type.");
106 }
107 }
108
109 /**
110 * Returns the {@link PrimitiveTypeEnum} enumeration element that represents
111 * the given primitive type.
112 *
113 * @param type a type node.
114 * @return the {@link PrimitiveTypeEnum} enumeration element that represents
115 * the given primitive type.
116 */
117 public static PrimitiveTypeEnum getPrimitiveType(final PrimitiveType type) {
118 return PrimitiveTypeEnum.valueOf(type.getName());
119 }
120
121 /**
122 * @param container a type container.
123 * @return the type node contained by the given container or <code>null</code>
124 * if the given container is empty.
125 */
126 public static Type getContainedType(final TypeContainer container) {
127 if (container.getPrimitiveType() != null) {
128 return container.getPrimitiveType();
129 }
130 if (container.getComplexType() != null) {
131 return container.getComplexType();
132 }
133 if (container.getArrayOf() != null) {
134 return container.getArrayOf();
135 }
136 if (container.getPointerOf() != null) {
137 return container.getPointerOf();
138 }
139 return null;
140 }
141
142 /**
143 * @param container a type container.
144 * @param type the type node to be added in the container.
145 * @throws IllegalArgumentException if the <code>type</code> is an unkown
146 * type.
147 */
148 public static void setContainedType(final TypeContainer container,
149 final Type type) {
150 if (type instanceof PrimitiveType) {
151 container.setPrimitiveType((PrimitiveType) type);
152 } else if (type instanceof ComplexType) {
153 container.setComplexType((ComplexType) type);
154 } else if (type instanceof ArrayOf) {
155 container.setArrayOf((ArrayOf) type);
156 } else if (type instanceof PointerOf) {
157 container.setPointerOf((PointerOf) type);
158 } else {
159 throw new IllegalArgumentException("Unknown type");
160 }
161 }
162
163 /**
164 * Returns the {@link IDLDefinition} contained by the given
165 * {@link ComplexType}.
166 *
167 * @param type a complex type node.
168 * @return the {@link IDLDefinition} contained by the given
169 * {@link ComplexType} or <code>null</code> if the given container
170 * is empty.
171 */
172 public static IDLDefinition getContainedDefinition(final ComplexType type) {
173 return type.getIDLDefinition();
174 }
175
176 /**
177 * Set the definition contained by the given {@link ComplexType} node.
178 *
179 * @param type a {@link ComplexType} node.
180 * @param definition the {@link IDLDefinition} to be contained in the
181 * {@link ComplexType} param.
182 */
183 public static void setContainedDefinition(final ComplexType type,
184 final IDLDefinition definition) {
185
186 type.setIDLDefinition(definition);
187 }
188
189 // ---------------------------------------------------------------------------
190 // Parameter utility methods
191 // ---------------------------------------------------------------------------
192
193 /**
194 * Returns <code>true</code> if the given parameter is "in" (ie.
195 * <code>Parameter.IN.equals(parameter.getQualifier())</code>).
196 *
197 * @param parameter a parameter node.
198 * @return <code>true</code> if the given parameter is "in".
199 */
200 public static boolean isInParameter(final Parameter parameter) {
201 return Parameter.IN.equals(parameter.getQualifier());
202 }
203
204 /**
205 * Returns <code>true</code> if the given parameter is "out" (ie.
206 * <code>Parameter.OUT.equals(parameter.getQualifier())</code>).
207 *
208 * @param parameter a parameter node.
209 * @return <code>true</code> if the given parameter is "out".
210 */
211 public static boolean isOutParameter(final Parameter parameter) {
212 return Parameter.OUT.equals(parameter.getQualifier());
213 }
214
215 /**
216 * Returns <code>true</code> if the given parameter is "in out" (ie.
217 * <code>Parameter.IN_OUT.equals(parameter.getQualifier())</code>).
218 *
219 * @param parameter a parameter node.
220 * @return <code>true</code> if the given parameter is "in out".
221 */
222 public static boolean isInOutParameter(final Parameter parameter) {
223 return Parameter.IN_OUT.equals(parameter.getQualifier());
224 }
225
226 /**
227 * Returns <code>true</code> if the given parameter is "const" (ie.
228 * <code>Parameter.CONST.equals(parameter.getQualifier())</code>).
229 *
230 * @param parameter a parameter node.
231 * @return <code>true</code> if the given parameter is "const".
232 */
233 public static boolean isConstParameter(final Parameter parameter) {
234 return Parameter.CONST.equals(parameter.getQualifier());
235 }
236
237 /**
238 * @param field
239 * @return <code>true</code> if the given {@link Field} is meant to be
240 * constant (<em>the semantic depends on the primitive programming
241 * language</em>),
242 * <code>false</code> otherwise.
243 */
244 public static boolean isConstField(final Field field) {
245 if (field.getQualifier().equals(Field.CONST)) {
246 return true;
247 }
248 return false;
249 }
250
251 // ---------------------------------------------------------------------------
252 // Method utility methods
253 // ---------------------------------------------------------------------------
254
255 /**
256 * Returns <code>true</code> if
257 * {@link Method#getHasVarParams() method.getHasVarParams()} is
258 * <code>"true"</code>.
259 *
260 * @param method a method.
261 * @return <code>true</code> if
262 * {@link Method#getHasVarParams() method.getHasVarParams()} is
263 * <code>"true"</code>.
264 */
265 public static boolean hasVarParams(final Method method) {
266 return Boolean.valueOf(method.getHasVarParams());
267 }
268
269 // ---------------------------------------------------------------------------
270 // Import utility methods
271 // ---------------------------------------------------------------------------
272
273 /**
274 * A decoration set on {@link Import} nodes that reference the imported
275 * {@link Node AST}.
276 *
277 * @see #setImportedAST(Import, Node)
278 * @see #getImportedAST(Import)
279 */
280 public static final String IMPORTED_AST_DECORATION = "idl-definition";
281
282 /**
283 * Sets the {@link #IMPORTED_AST_DECORATION} decoration to the given node with
284 * the {@link IDLDefinition}.
285 *
286 * @param i the import node to which the decoration is set.
287 * @param ast the value of the decoration.
288 * @see #IMPORTED_AST_DECORATION
289 */
290 public static void setImportedAST(final Import i, final Node ast) {
291 i.astSetDecoration(IMPORTED_AST_DECORATION, ast);
292 }
293
294 /**
295 * Returns the value of the {@link #IMPORTED_AST_DECORATION} decoration of the
296 * given import node.
297 *
298 * @param i an import node.
299 * @return The value of the {@link #IMPORTED_AST_DECORATION} decoration or
300 * <code>null</code> if the given node has no such decoration.
301 * @see #IMPORTED_AST_DECORATION
302 */
303 public static Node getImportedAST(final Import i) {
304 return (Node) i.astGetDecoration(IMPORTED_AST_DECORATION);
305 }
306
307 /**
308 * Returns the Method with the given name or null if none is found.
309 *
310 * @param methodContainer The method container node.
311 * @param name the name of the {@link Method} to be found.
312 * @return the {@link Method} method with the given <code>name</code>, or
313 * <code>null</code> if none is found.
314 */
315 public static Method getMethodByName(final MethodContainer methodContainer,
316 final String name) {
317
318 if (name == null || name.length() == 0) {
319 throw new IllegalArgumentException("Method name can't be null or empty");
320 }
321
322 final Method[] methods = methodContainer.getMethods();
323 for (final Method m : methods) {
324 if (m.getName().equals(name)) {
325 return m;
326 }
327 }
328
329 /* no method with that name found, return null */
330 return null;
331 }
332 }