View Javadoc

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 }