1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.objectweb.fractal.cecilia.primitive.thinkMC.implementations;
26
27 import static org.objectweb.fractal.adl.NodeUtil.castNodeError;
28 import static org.objectweb.fractal.cecilia.adl.implementations.ImplementationDecorationUtil.getCode;
29 import static org.objectweb.fractal.cecilia.adl.implementations.ImplementationHelper.hasConstructor;
30 import static org.objectweb.fractal.cecilia.adl.implementations.ImplementationHelper.hasDestructor;
31
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.List;
35 import java.util.Map;
36
37 import org.objectweb.fractal.adl.ADLException;
38 import org.objectweb.fractal.adl.CompilerError;
39 import org.objectweb.fractal.adl.ComponentVisitor;
40 import org.objectweb.fractal.adl.Node;
41 import org.objectweb.fractal.adl.components.ComponentContainer;
42 import org.objectweb.fractal.adl.error.GenericErrors;
43 import org.objectweb.fractal.adl.implementations.Implementation;
44 import org.objectweb.fractal.adl.implementations.ImplementationContainer;
45 import org.objectweb.fractal.api.Component;
46 import org.objectweb.fractal.cecilia.adl.AbstractDefinitionTask;
47 import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
48 import org.objectweb.fractal.cecilia.adl.directives.Include;
49 import org.objectweb.fractal.cecilia.adl.directives.IncludeContainer;
50 import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
51 import org.objectweb.fractal.cecilia.adl.file.SourceFile;
52 import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
53 import org.objectweb.fractal.task.core.TaskException;
54 import org.objectweb.fractal.task.core.TaskFactory;
55 import org.objectweb.fractal.task.core.primitive.annotations.ClientInterface;
56 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
57 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
58 import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
59
60
61
62
63
64 public class MacroDefinitionVisitor extends AbstractTaskFactoryUser
65 implements
66 ComponentVisitor {
67
68
69
70
71
72
73
74
75
76
77 public Component visit(final List<Node> path,
78 final ComponentContainer container, final Map<Object, Object> context)
79 throws ADLException, TaskException {
80 final Implementation impl = castNodeError(container,
81 ImplementationContainer.class).getImplementation();
82 if (impl == null) {
83 throw new CompilerError(GenericErrors.INTERNAL_ERROR,
84 "This visitor is only applicable for primitive component.");
85 }
86 final Component implTask = createImplementationTask(container, impl);
87 if (impl instanceof IncludeContainer
88 && ((IncludeContainer) impl).getIncludes().length != 0) {
89 final Include[] includes = ((IncludeContainer) impl).getIncludes();
90
91 final Collection<Component> tasks = new ArrayList<Component>(
92 includes.length + 1);
93 tasks.add(implTask);
94
95 for (final Include include : includes) {
96
97
98 if (!((SourceFile) getCode((Node) include)).isAssemblyFile())
99 tasks.add(createModuleImplementationTask(container, include));
100 }
101 return taskFactoryItf.newCompositeTask(tasks, TaskFactory.EXPORT_ALL,
102 null);
103 } else {
104 return implTask;
105 }
106 }
107
108
109
110
111
112 protected Component createImplementationTask(
113 final ComponentContainer container, final Implementation impl)
114 throws TaskException {
115 return taskFactoryItf.newPrimitiveTask(new ImplementationTask(
116 hasConstructor(container), hasDestructor(container)), container);
117 }
118
119 protected Component createModuleImplementationTask(
120 final ComponentContainer container, final Include include)
121 throws TaskException {
122 return taskFactoryItf.newPrimitiveTask(new ModuleImplementationTask(
123 hasConstructor(container), hasDestructor(container)), container,
124 include);
125 }
126
127
128
129
130
131 protected abstract static class AbstractImplementationTask
132 extends
133 AbstractDefinitionTask {
134
135 protected final boolean hasConstructor;
136 protected final boolean hasDestructor;
137
138
139
140
141
142
143
144
145
146
147 public AbstractImplementationTask(final boolean hasConstructor,
148 final boolean hasDestructor) {
149 this.hasConstructor = hasConstructor;
150 this.hasDestructor = hasDestructor;
151 }
152
153
154
155
156
157 protected abstract void appendImplementationCode(CodeWriter cw);
158
159
160
161
162
163 @Override
164 protected String processSourceCode() throws Exception {
165 final CodeWriter cw = new CodeWriter(
166 "Primitive Implementation Definition Builder");
167 final String componentCName = typeNameProviderItf.getCTypeName();
168
169
170 cw.append("#define DECLARE_DATA \\").endl();
171 cw.append(" struct ").append(componentCName).append("_instancedata")
172 .endl();
173
174 if (hasConstructor) {
175 cw.append("#define CONSTRUCTOR \\").endl();
176 cw.append(componentCName).append("_constructor").endl();
177 }
178 if (hasDestructor) {
179 cw.append("#define DESTRUCTOR \\").endl();
180 cw.append(componentCName).append("_destructor").endl();
181 }
182
183 cw.append("#define METHOD(i, m) \\").endl();
184 cw.append(componentCName).append("##_##i##_##m##_method").endl();
185 cw.append("#define CALLMINE(itf,proc,args...) \\").endl();
186 cw.append(" ").append(componentCName).append(
187 "##_##itf##_##proc##_method(_this, ##args)").endl();
188
189 cw.append("#define REQUIRED \\").endl();
190 cw.append(" ((struct ").append(componentCName).append(
191 "_t *)_this)->type.imported ").endl();
192 cw.append("#define ATTRIBUTES \\").endl();
193 cw.append(" ((struct ").append(componentCName).append(
194 "_t *)_this)->attributes ").endl();
195 cw.append("#define DATA \\").endl();
196 cw.append(" ((struct ").append(componentCName + "_t *)_this)->data ")
197 .endl();
198
199 cw.append("#define GETSELF \\").endl();
200 cw.append(" struct ").append(componentCName).append(
201 "_t *self = (struct " + componentCName).append("_t *) _this ").endl();
202
203
204 cw.append("#define GET_MY_OWNER \\").endl();
205 cw.append(" ((Rfractal_api_Component *) _this)").endl();
206
207
208 cw.append("#define GET_MY_INTERFACE(itf) \\").endl();
209 cw.append(" (&(((struct ").append(componentCName).append(
210 "_t *)_this)->type.exported.itf))").endl();
211
212 if (hasConstructor) {
213 cw.appendln("// declare constructor.");
214 cw.appendln("void CONSTRUCTOR(void *_this);");
215 }
216 if (hasDestructor) {
217 cw.appendln("// declare destructor.");
218 cw.appendln("void DESTRUCTOR(void *_this);");
219 }
220
221
222 appendImplementationCode(cw);
223 return cw.toString();
224 }
225 }
226
227
228
229
230
231
232 @TaskParameters("componentNode")
233 @ServerInterfaces(@ServerInterface(name = "implementation-provider", signature = SourceCodeProvider.class, record = "role:implementation, id:%", parameters = "componentNode"))
234 public static class ImplementationTask extends AbstractImplementationTask {
235
236
237
238
239
240
241 @ClientInterface(name = "implementation-source-code", record = "role:implementationSourceCode, id:%", parameters = "componentNode")
242 public SourceCodeProvider implementationSourceCodeProviderItf;
243
244
245
246
247
248
249
250
251
252
253 public ImplementationTask(final boolean hasConstructor,
254 final boolean hasDestructor) {
255 super(hasConstructor, hasDestructor);
256 }
257
258
259
260
261
262 @Override
263 protected void appendImplementationCode(final CodeWriter cw) {
264 cw.appendln(implementationSourceCodeProviderItf.getSourceCode());
265
266 cw.append("#ifndef __CECILIA__COMPONENT_TYPE_DEFINITION_DONE").endl();
267 cw.append(
268 "#warning implementation file should include the header cecilia.h")
269 .endl();
270 cw.append("#endif").endl();
271 }
272 }
273
274
275
276
277
278
279 @TaskParameters({"componentNode", "moduleNode"})
280 @ServerInterfaces(@ServerInterface(name = "implementation-provider", signature = SourceCodeProvider.class, record = "role:implementation, id:%, module:%", parameters = {
281 "componentNode", "moduleNode"}))
282 public static class ModuleImplementationTask
283 extends
284 AbstractImplementationTask {
285
286
287
288
289
290
291 @ClientInterface(name = "implementation-source-code", record = "role:implementationSourceCode, id:%, module:%", parameters = {
292 "componentNode", "moduleNode"})
293 public SourceCodeProvider implementationModuleSourceCodeProviderItf;
294
295
296
297
298
299
300
301
302
303
304 public ModuleImplementationTask(final boolean hasConstructor,
305 final boolean hasDestructor) {
306 super(hasConstructor, hasDestructor);
307 }
308
309
310
311
312
313 @Override
314 protected void appendImplementationCode(final CodeWriter cw) {
315 cw.appendln(implementationModuleSourceCodeProviderItf.getSourceCode());
316 }
317 }
318 }