Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / codegen / java / JavaInitVisitor.java @ 7

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas.codegen.java;
29

    
30
import java.util.ArrayList;
31
import java.util.HashSet;
32

    
33
import org.momut.ooas.ast.AstNodeTypeEnum;
34
import org.momut.ooas.ast.IAst;
35
import org.momut.ooas.ast.expressions.Expression;
36
import org.momut.ooas.ast.identifiers.AttributeIdentifier;
37
import org.momut.ooas.ast.identifiers.EnumIdentifier;
38
import org.momut.ooas.ast.identifiers.Identifier;
39
import org.momut.ooas.ast.identifiers.IdentifierKind;
40
import org.momut.ooas.ast.identifiers.MainModule;
41
import org.momut.ooas.ast.types.EnumType;
42
import org.momut.ooas.ast.types.OoActionSystemInstance;
43
import org.momut.ooas.ast.types.OoActionSystemType;
44
import org.momut.ooas.ast.types.TupleType;
45
import org.momut.ooas.ast.types.TypeKind;
46
import org.momut.ooas.ast.types.UlyssesType;
47
import org.momut.ooas.codegen.OoasCodeEmitter;
48
import org.momut.ooas.parser.ParserError;
49
import org.momut.ooas.parser.ParserMessage;
50
import org.momut.ooas.parser.ParserState;
51
import org.momut.ooas.visitors.OoaCompleteAstTraversalVisitor;
52

    
53
public final class JavaInitVisitor extends OoaCompleteAstTraversalVisitor
54
{
55
        private final String SimulationNameSpace = "org.momut.ooas.codegen.java.simulation";
56
        private final OoasCodeEmitter emitter;
57
        private final ArrayList<UlyssesType> hiddenTypesStillToEmit = new ArrayList<UlyssesType>();
58
        private final Scratchbook scratchbook = new Scratchbook();
59
        private StringBuilder helpers = new StringBuilder();
60

    
61

    
62

    
63
        private final ArrayList<OoActionSystemType> autoConsList = new ArrayList<OoActionSystemType>();
64

    
65
        private int m_maxObjectNameLength = 0;
66
        private final ArrayList<String> m_objectNames = new ArrayList<String>();
67
        private final ArrayList<OoActionSystemInstance> m_initialObjectWorkingSet = new ArrayList<OoActionSystemInstance>();
68

    
69

    
70

    
71
        public int maxObjectNameLength() { return m_maxObjectNameLength; }
72
        public ArrayList<String> objectNames() { return m_objectNames; }
73
        public ArrayList<OoActionSystemInstance> initialObjectWorkingSet() { return m_initialObjectWorkingSet; }
74
        public HashSet<String> givenObjectNames = new HashSet<String>();
75

    
76

    
77
        public void Error(int line, int pos, String p)
78
        {
79
                final ParserError error = new ParserError(m_ParserState.filename, line, pos, p);
80
                m_ParserState.AddErrorMessage(error);
81
        }
82

    
83

    
84
//        private void Error(OoActionSystemInstance id, String p)
85
//        {
86
//                int line = id.Type.identifier().line();
87
//                int pos = id.Type.identifier().column();
88
//
89
//                ParserError error = new ParserError(m_ParserState.filename, line, pos, p);
90
//                m_ParserState.AddErrorMessage(error);
91
//        }
92
//        private void Warning(OoActionSystemType atype, String p)
93
//        {
94
//                ParserWarning warn = new ParserWarning(m_ParserState.filename, atype.identifier().line(),
95
//                                atype.identifier().column(), p);
96
//                m_ParserState.AddWarningMessage(warn);
97
//        }
98

    
99
        private String GetIdentifierString(String anIdentifier)
100
        {
101
                return JavaIdentifier.GetIdentifierString(anIdentifier);
102
        }
103
        private final ArrayList<OoActionSystemType> AstTypeLookup = new ArrayList<OoActionSystemType>();
104

    
105
        /// <summary>
106
        /// here we are called when a new object has been created
107
        /// </summary>
108
        void visit(ActionSystemClass actionSystemClass, int ConstrNum)
109
        {
110
//                OoActionSystemType aParentType = actionSystemClass.parent != null
111
//                        ? AstTypeLookup.get(actionSystemClass.parent._AstTypeLookupIndex)
112
//                        : null;
113
                OoActionSystemType atype = AstTypeLookup.get(actionSystemClass._AstTypeLookupIndex);
114
                final OoActionSystemInstance aParentInstance = actionSystemClass.parent != null
115
                        ? actionSystemClass.parent.objectInstance
116
                        : null;
117

    
118
                final HashSet<UlyssesType> seenTypes = new HashSet<UlyssesType>();
119
                final StringBuilder instantiationPath = new StringBuilder();
120
                if (aParentInstance != null)
121
                {
122
                        OoActionSystemInstance tmp = aParentInstance;
123
                        while (tmp != null)
124
                        {
125
                                instantiationPath.append(String.format("<-%s", tmp.Name));
126
                                seenTypes.add(tmp.Type);
127
                                tmp = tmp.ParentObject;
128
                        }
129
                }
130

    
131
                UlyssesType tmpType = atype;
132
                while (tmpType != null)
133
                {
134
                        if (seenTypes.contains(tmpType))
135
                        {
136
                                throw new JavaInitVisitorCompileException(String.format("Cycle in object creation. %s", instantiationPath.toString()));
137
                        }
138
                        else
139
                                tmpType = ((OoActionSystemType)tmpType).baseType();
140
                }
141

    
142
                actionSystemClass.objectInstance =
143
                                new OoActionSystemInstance(actionSystemClass.objectName, atype, actionSystemClass, aParentInstance);
144

    
145
                // update max length of object name
146
                m_maxObjectNameLength = actionSystemClass.objectName.length() > m_maxObjectNameLength
147
                        ? actionSystemClass.objectName.length()
148
                        : m_maxObjectNameLength;
149

    
150
                // add to list of object names
151
                m_objectNames.add(actionSystemClass.objectName);
152

    
153
                // add to global list of initial objects
154
                m_initialObjectWorkingSet.add(actionSystemClass.objectInstance);
155

    
156
                m_ParserState.AddMessage(new ParserMessage(m_ParserState.filename,
157
                        atype.identifier().line(), atype.identifier().column(), String.format("Creating object: %s", actionSystemClass.objectName)));
158

    
159
                atype.objects().add(actionSystemClass.objectInstance);
160
                // also add the object to the base types
161
                atype = atype.baseType();
162
                while (atype != null)
163
                {
164
                        atype.derivedObjects().add(actionSystemClass.objectInstance);
165
                        atype = atype.baseType();
166
                }
167
                atype = null;
168

    
169
                if (ConstrNum >= 0)
170
                        scratchbook.constructors().get(ConstrNum).AddInstance(actionSystemClass.objectInstance);
171
        }
172
        private String GetCSharpType(UlyssesType aType)
173
        {
174
                if (aType.isAnonymousType())
175
                        hiddenTypesStillToEmit.add(aType);
176

    
177
                final JavaType sharptype = new JavaType();
178
                aType.Accept(sharptype);
179
                return sharptype.toString();
180
        }
181
        private String GetCSharpExpression(Expression anExpression)
182
        {
183
                final JavaExpression sharpexpression = new JavaExpression(helpers, scratchbook);
184
                anExpression.Accept(sharpexpression);
185
                return sharpexpression.toString();
186
        }
187

    
188
        private void StartSimulation(String p)
189
        {
190
                try
191
                {
192
                        // set reference
193
                        //ActionSystemClass.objectInstantiator = this;
194
                        // compile
195
                        final Class<?> simulationCode = JavaCodeCompiler.compileCode(p, "Wrapper", SimulationNameSpace, m_ParserState);
196
                        // execute system initialization
197
                        JavaCodeCompiler.ExecuteCode(simulationCode, "Start", this, m_ParserState);
198
                }
199
                catch (final JavaInitVisitorCompileException e)
200
                {
201
                        final ParserError error = new ParserError("ObjectInstantiationVisitor.cs", 0, 0, e.getMessage());
202
                        m_ParserState.AddErrorMessage(error);
203
                }
204
        }
205

    
206
        /// <summary>
207
        /// generates C# code that describes initialization of the action systems
208
        /// this is used to determine the initial working set of classes.
209
        /// </summary>
210
        private void Emit(OoActionSystemType ooActionSystemType)
211
        {
212
                final ArrayList<AttributeIdentifier> initializers = new ArrayList<AttributeIdentifier>();
213
                helpers = new StringBuilder();
214
                if (ooActionSystemType.baseType() == null)
215
                        emitter.AppendLineIncIndent(String.format("public class %s extends org.momut.ooas.codegen.java.ActionSystemClass {", GetIdentifierString(ooActionSystemType.identifier().tokenText())));
216
                else
217
                        emitter.AppendLineIncIndent(String.format("public class %s extends %s {", GetIdentifierString(ooActionSystemType.identifier().tokenText()), GetIdentifierString(ooActionSystemType.baseType().identifier().tokenText())));
218

    
219
                for (final Identifier attr: ooActionSystemType.symbols().symbolList())
220
                {
221
                        if (attr.kind() == IdentifierKind.AttributeIdentifier)
222
                        {
223
                                final String staticdecl = ((AttributeIdentifier)attr).isStatic() ? "static" : "";
224
                                emitter.AppendLine(String.format("public %s %s %s;",
225
                                                staticdecl,
226
                                                GetCSharpType(attr.type()),
227
                                                GetIdentifierString(attr.tokenText())));
228
                                initializers.add(((AttributeIdentifier)attr));
229
                        }
230
                }
231

    
232
                // emit internal constructor that initializes object
233
                emitter.AppendLineIncIndent(String.format("protected %s (org.momut.ooas.codegen.java.ActionSystemClass parent, int constrNum, int LookupIndex, String aGivenName) {", GetIdentifierString(ooActionSystemType.identifier().tokenText())));
234
                emitter.AppendLine("this(parent, constrNum, LookupIndex, aGivenName, m_visitor);");
235
                emitter.AppendLineDecIndent("}");
236

    
237
                emitter.AppendLineIncIndent(String.format("protected %s (org.momut.ooas.codegen.java.ActionSystemClass parent, int constrNum, int LookupIndex, String aGivenName, org.momut.ooas.codegen.java.JavaInitVisitor visitor) {", GetIdentifierString(ooActionSystemType.identifier().tokenText())));
238
                emitter.AppendLine("super(parent, constrNum, LookupIndex, aGivenName, visitor);");
239
                for (final AttributeIdentifier attr: initializers)
240
                        emitter.AppendLine(String.format("%s = %s;", GetIdentifierString(attr.tokenText()), GetCSharpExpression(attr.initializer())));
241
                emitter.AppendLineDecIndent("}");
242

    
243

    
244
                // emit public constructor
245
                emitter.AppendLine(String.format("public %s (org.momut.ooas.codegen.java.ActionSystemClass parent, int constrNum) {this(parent, constrNum, %s, \"\");}", GetIdentifierString(ooActionSystemType.identifier().tokenText()), AstTypeLookup.size()));
246

    
247
                // emit public constructor with fixed name
248
                emitter.AppendLine(String.format("public %s (org.momut.ooas.codegen.java.ActionSystemClass parent, int constrNum, String aName) {this(parent, constrNum, %s, aName);}", GetIdentifierString(ooActionSystemType.identifier().tokenText()), AstTypeLookup.size()));
249

    
250

    
251
                AstTypeLookup.add(ooActionSystemType);
252

    
253
                // emit helpers
254
                emitter.Append(helpers.toString());
255

    
256
                emitter.AppendLineDecIndent("}");
257

    
258
                if (ooActionSystemType.autoConstruction())
259
                        autoConsList.add(ooActionSystemType);
260
        }
261

    
262
        /// <summary>
263
        /// Emits type definition for tuple
264
        /// </summary>
265
        private void Emit(TupleType atupleType)
266
        {
267
                emitter.AppendLineIncIndent(String.format("public static class %s {", GetIdentifierString(atupleType.identifier().tokenText())));
268
                int i = 0;
269
                for (final UlyssesType it: atupleType.innerTypes())
270
                {
271
                        emitter.AppendLine(String.format("public %s elem_%s;", GetCSharpType(it), Integer.toString(i)));
272
                        i++;
273
                }
274

    
275
                emitter.AppendLine(" /*constr*/ ");
276
                emitter.Append(String.format("public %s (", GetIdentifierString(atupleType.identifier().tokenText())));
277
                i = 0;
278
                for (final UlyssesType it: atupleType.innerTypes())
279
                {
280
                        if (i != 0)
281
                                emitter.Append(",");
282
                        emitter.Append(String.format("%s arg_%s", GetCSharpType(it), Integer.toString(i)));
283
                        i++;
284
                }
285
                emitter.AppendLineIncIndent(") {");
286
                for (i = 0; i < atupleType.innerTypes().size(); i++)
287
                        emitter.AppendLine(String.format("elem_%s = arg_%s;", i,i));
288

    
289
                emitter.AppendLineDecIndent("}");
290

    
291
                emitter.AppendLineDecIndent("}");
292
        }
293

    
294
        /// <summary>
295
        /// Emits type definition for enum
296
        /// </summary>
297
        private void Emit(EnumType anEnum)
298
        {
299
                emitter.Append(String.format("public enum %s {", GetIdentifierString(anEnum.identifier().tokenText())));
300
                int i = 0;
301
                for (final EnumIdentifier it: anEnum.listOfEnumSymbols())
302
                {
303
                        if (i != 0)
304
                                emitter.Append(", ");
305
                        else
306
                                i++;
307
                        emitter.Append(GetIdentifierString(it.tokenText()));
308
                }
309
                emitter.AppendLine("}");
310
        }
311

    
312
        @Override
313
        protected void VisitAstElement(IAst element, IAst parent)
314
        {
315
                if (element.nodeType() == AstNodeTypeEnum.type &&
316
                                ((UlyssesType)element).kind() == TypeKind.OoActionSystemType)
317
                {
318
                        /*OoActionSystemType asystem = (OoActionSystemType)element;
319
                        if (asystem.autoConstruction)
320
                CheckForRecursiveNew(asystem);*/
321
                        Emit((OoActionSystemType)element);
322
                }
323
                else if (element.nodeType() == AstNodeTypeEnum.type &&
324
                                ((UlyssesType)element).kind() == TypeKind.TupleType)
325
                {
326
                        Emit((TupleType)element);
327
                }
328
                else if (element.nodeType() == AstNodeTypeEnum.type &&
329
                                ((UlyssesType)element).kind() == TypeKind.EnumeratedType)
330
                {
331
                        Emit((EnumType)element);
332
                }
333
                else
334
                        super.VisitAstElement(element, parent);
335
        }
336

    
337
        @Override
338
        public void visit(MainModule mainModule)
339
        {
340
                scratchbook.constructors().clear();
341
                emitter.AppendLine(String.format("package %s;",SimulationNameSpace));
342
//                emitter.AppendLine("import org.momut.ooas.codegen.java.*;");
343
                emitter.AppendLine("");
344

    
345
                emitter.AppendLineIncIndent("public final class Wrapper {");
346
                emitter.AppendLine("private org.momut.ooas.codegen.java.JavaInitVisitor m_visitor;");
347

    
348
                super.visit(mainModule);
349

    
350
                emitter.AppendLine(" /* == anonymous types == */ ");
351
                for (final UlyssesType x: hiddenTypesStillToEmit)
352
                {
353
                        // we only need to define tuples and enums..
354
                        if (x.kind() == TypeKind.TupleType)
355
                                Emit((TupleType)x);
356
                        else if (x.kind() == TypeKind.EnumeratedType)
357
                                Emit((EnumType)x);
358
                }
359

    
360
                emitter.AppendLine(" /* == create autocons objects == */ ");
361
                emitter.AppendLineIncIndent("public void start(org.momut.ooas.codegen.java.JavaInitVisitor visitor){");
362
                emitter.AppendLine("m_visitor = visitor;");
363
                for (final OoActionSystemType x: autoConsList)
364
                        emitter.AppendLine(String.format("new %s(null,-1 /*autocons*/);", GetIdentifierString(x.identifier().tokenText())));
365
                emitter.AppendLine("m_visitor = null;");
366
                emitter.AppendLineDecIndent("}");
367

    
368
                emitter.AppendLine(" /* == setup wrapper class, init object and run the code == */ ");
369
                emitter.AppendLineIncIndent("public static void Start(org.momut.ooas.codegen.java.JavaInitVisitor visitor){");
370
                emitter.AppendLine("final Wrapper wrapper = new Wrapper();");
371
                emitter.AppendLine("wrapper.start(visitor);");
372
                emitter.AppendLineDecIndent("}");
373

    
374
                emitter.AppendLineDecIndent("}"); // wrapper
375

    
376
                StartSimulation(emitter.toString());
377
        }
378

    
379

    
380
        @Override
381
        public String toString()
382
        {
383
                return emitter.toString();
384
        }
385

    
386
        public JavaInitVisitor(ParserState state)
387
        {
388
                super (state);
389
                emitter = new OoasCodeEmitter();
390
        }
391

    
392
}