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:Ali Erdem Ozcan
22   *
23   */
24  
25  package org.objectweb.fractal.cecilia.adl.idl;
26  
27  import java.util.ArrayList;
28  import java.util.LinkedHashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  import org.objectweb.fractal.adl.ADLException;
33  import org.objectweb.fractal.adl.Node;
34  import org.objectweb.fractal.api.Component;
35  import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
36  import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
37  import org.objectweb.fractal.cecilia.adl.idl.ast.Field;
38  import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinition;
39  import org.objectweb.fractal.cecilia.adl.idl.ast.Import;
40  import org.objectweb.fractal.cecilia.adl.idl.ast.ImportContainer;
41  import org.objectweb.fractal.cecilia.adl.idl.ast.InterfaceDefinition;
42  import org.objectweb.fractal.cecilia.adl.idl.ast.Method;
43  import org.objectweb.fractal.cecilia.adl.idl.ast.PrimitiveType;
44  import org.objectweb.fractal.cecilia.adl.idl.ast.TypeContainer;
45  import org.objectweb.fractal.cecilia.adl.idl.util.CUtil;
46  import org.objectweb.fractal.cecilia.adl.idl.util.Util;
47  import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
48  import org.objectweb.fractal.task.core.Executable;
49  import org.objectweb.fractal.task.core.TaskException;
50  import org.objectweb.fractal.task.core.primitive.annotations.ClientInterfaceForEach;
51  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
52  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
53  import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
54  
55  /**
56   * Visitor component for interface definition in C.
57   */
58  public class CInterfaceDefinitionVisitor extends AbstractTaskFactoryUser
59      implements
60        IDLDefinitionVisitor {
61  
62    // ---------------------------------------------------------------------------
63    // Implementation of the IDLVisitor interface
64    // ---------------------------------------------------------------------------
65  
66    /**
67     * Visits {@link InterfaceDefiniton} nodes, and creates a task that writes the
68     * corresponding C source code.
69     */
70    public Component visit(final List<Node> path,
71        final IDLDefinition idlDefinition, final Map<Object, Object> context)
72        throws ADLException, TaskException {
73      /* this component can be used only to compile InterfaceDefinition types */
74      if (idlDefinition instanceof InterfaceDefinition) {
75  
76        final List<IDLDefinition> importedDefinitions = new ArrayList<IDLDefinition>();
77        if (idlDefinition instanceof ImportContainer) {
78          for (final Import imp : ((ImportContainer) idlDefinition).getImports()) {
79            importedDefinitions.add((IDLDefinition) Util.getImportedAST(imp));
80          }
81        }
82  
83        return taskFactoryItf.newPrimitiveTask(new CInterfaceHeaderTask(
84            (InterfaceDefinition) idlDefinition), idlDefinition,
85            importedDefinitions);
86      } else
87        return null;
88    }
89  
90    // ---------------------------------------------------------------------------
91    // Task classes
92    // ---------------------------------------------------------------------------
93  
94    /**
95     * Builds interface definitions for C. It extends the Abstract Interface
96     * visitor and implements the required visit methods.
97     */
98    @TaskParameters({"interfaceDefinitionNode", "importedDefinitions"})
99    @ServerInterfaces(@ServerInterface(name = "c-interface-definition-provider", signature = SourceCodeProvider.class, record = "role:cInterfaceDefinition, id:%", parameters = {"interfaceDefinitionNode"}))
100   public static class CInterfaceHeaderTask extends AbstractInterfaceVisitor
101       implements
102         Executable,
103         SourceCodeProvider {
104 
105     protected final InterfaceDefinition                 itfDefinition;
106 
107     // -------------------------------------------------------------------------
108     // Client interfaces
109     // -------------------------------------------------------------------------
110 
111     /** Source code to be included to access to definition of imported IDLs. */
112     @ClientInterfaceForEach(iterable = "importedDefinitions", prefix = "imported-definition", signature = SourceCodeProvider.class, record = "role:importedDefinition, id:%", parameters = "importedDefinitions.element")
113     public final Map<IDLDefinition, SourceCodeProvider> importedDefinitionItfs = new LinkedHashMap<IDLDefinition, SourceCodeProvider>();
114 
115     // -------------------------------------------------------------------------
116     // Task constructor
117     // -------------------------------------------------------------------------
118 
119     /**
120      * @param itfDefinition The interface definition node for which this task
121      *            must generate C source code.
122      */
123     public CInterfaceHeaderTask(final InterfaceDefinition itfDefinition) {
124       this.itfDefinition = itfDefinition;
125     }
126 
127     // The generated source code.
128     protected String     sourceCode;
129     // The code writer that is used for code generation
130     protected CodeWriter cw;
131     // The name of the interface (in IDL naming space)
132     protected String     itfName;
133     // The name of the interface (in C naming space)
134     protected String     cItfName;
135 
136     // -------------------------------------------------------------------------
137     // Implementation of the Executable interface
138     // -------------------------------------------------------------------------
139 
140     public void execute() throws Exception {
141       cw = new CodeWriter("C Interface builder");
142       itfName = itfDefinition.getName();
143       cItfName = itfName.replace('.', '_');
144       // Visit
145       visit(itfDefinition);
146       cw.endl();
147       sourceCode = cw.toString();
148     }
149 
150     // -------------------------------------------------------------------------
151     // Implementation of the SourceCodeProvider interface
152     // -------------------------------------------------------------------------
153 
154     public String getSourceCode() {
155       return sourceCode;
156     }
157 
158     // -------------------------------------------------------------------------
159     // Implementation of the visitor methods
160     // -------------------------------------------------------------------------
161 
162     public void enterInterface(final InterfaceDefinition itf) throws Exception {
163       cw.append("/* Interface ").append(itfName).endl();
164       cw.appendln("Generated automatically, do not edit ! */");
165       cw.endl();
166 
167       cw.append("#ifndef H").append(cItfName).endl();
168       cw.append("#define H").append(cItfName).endl();
169       cw.endl();
170 
171       cw.append("// Interface descriptor");
172       cw.append("struct M").append(cItfName).append(";").endl();
173       cw.appendln("typedef struct {");
174       cw.append("  struct M").append(cItfName).append(" *meth;").endl();
175       cw.appendln("  void *selfdata;");
176       cw.appendln("#if defined(TYPEDINTERFACE)");
177       cw.appendln("  const char *type;");
178       cw.appendln("#endif");
179       cw.append("} ");
180       cw.append(" *").append(cItfName).append(",");
181       /* typedef with "R" is leaved for legacy reason. */
182       cw.append(" R").append(cItfName).append(";").endl();
183 
184       for (final SourceCodeProvider importedDefinitionProvider : importedDefinitionItfs
185           .values()) {
186         cw.append(importedDefinitionProvider.getSourceCode());
187       }
188 
189       /* include the definition of the cecilia short cut types */
190       cw.endl();
191       cw.append("/* some cecilia typedefs for predefinite C types */").endl();
192       cw.append("#include \"cecilia_types.h\"").endl();
193       cw.endl();
194 
195       cw.endl();
196 
197       cw.appendln("  /* Virtual table */");
198       cw.append("struct M").append(cItfName).append(" {").endl();
199     }
200 
201     public void leaveInterface(final InterfaceDefinition itf) throws Exception {
202       cw.append("};").endl().endl();
203       cw.appendln("#endif");
204     }
205 
206     public void visitMethod(final Method method) throws Exception {
207       cw.append(CUtil.buildMethodDefinition(method, true)).append(";").endl();
208     }
209 
210     public void visitField(final Field field) throws Exception {
211       final PrimitiveType type = ((TypeContainer) field).getPrimitiveType();
212       cw.append("#define ").append(cItfName).append("_")
213           .append(field.getName()).append(" ((").append(
214               CUtil.buildPrimitiveType(type)).append(") ").append(
215               field.getValue()).append(')').endl();
216       cw.endl();
217     }
218   }
219 }