Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / visitors / OoaObjectInstantiationVisitor.java @ 12

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.visitors;
29

    
30
import org.momut.ooas.CompilerConfiguration.LabelCompression;
31
import org.momut.ooas.ast.IScope;
32
import org.momut.ooas.ast.identifiers.AttributeIdentifier;
33
import org.momut.ooas.ast.identifiers.FunctionIdentifier;
34
import org.momut.ooas.ast.identifiers.Identifier;
35
import org.momut.ooas.ast.identifiers.IdentifierKind;
36
import org.momut.ooas.ast.identifiers.IdentifierList;
37
import org.momut.ooas.ast.identifiers.MainModule;
38
import org.momut.ooas.ast.identifiers.MethodIdentifier;
39
import org.momut.ooas.ast.identifiers.NamedActionIdentifier;
40
import org.momut.ooas.ast.identifiers.SelfTypeIdentifier;
41
import org.momut.ooas.ast.identifiers.TypeIdentifier;
42
import org.momut.ooas.ast.statements.Block;
43
import org.momut.ooas.ast.statements.NondetBlock;
44
import org.momut.ooas.ast.statements.PrioBlock;
45
import org.momut.ooas.ast.statements.SeqBlock;
46
import org.momut.ooas.ast.statements.Statement;
47
import org.momut.ooas.ast.types.ActionSystem;
48
import org.momut.ooas.ast.types.FunctionType;
49
import org.momut.ooas.ast.types.OoActionSystemInstance;
50
import org.momut.ooas.ast.types.OoActionSystemType;
51
import org.momut.ooas.ast.types.TypeKind;
52
import org.momut.ooas.codegen.java.JavaInitVisitor;
53
import org.momut.ooas.parser.ParserError;
54
import org.momut.ooas.parser.ParserState;
55
import org.momut.ooas.parser.SymbolTable;
56
import org.momut.ooas.utils.OoasCompilerHashMap;
57
import org.momut.ooas.utils.exceptions.NotImplementedException;
58

    
59
public final class OoaObjectInstantiationVisitor extends OoaCompleteAstTraversalVisitor
60
{
61
        private final JavaInitVisitor m_simulator;
62
        private final OoaIdentifierCompressVisitor m_compressor;
63
        private ActionSystem m_actionSystem;
64
        private Identifier self;
65
        private OoasCompilerHashMap<Object, Object> m_toReplace = new OoasCompilerHashMap<Object, Object>();
66

    
67
        /// <summary>
68
        /// for a given object and type, the method duplicates the attributes and adds them to the resulting
69
        /// instantiated action system.
70
        /// </summary>
71
        private void DuplicateAttribute(AttributeIdentifier attributeIdentifier,
72
                        OoActionSystemInstance obj, OoActionSystemType aType, ActionSystem m_actionSystem)
73
        {
74
                final AttributeIdentifier newAttribute = new AttributeIdentifier(attributeIdentifier);
75
                newAttribute.SetTokenText(String.format("%s_%s", obj.Name, attributeIdentifier.tokenText()));
76
                m_toReplace.putSafe(attributeIdentifier, newAttribute);
77

    
78
                newAttribute.SetInitializer(newAttribute.initializer().Clone());
79
                m_toReplace.putSafe(attributeIdentifier.initializer(), newAttribute.initializer());
80
                final OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
81
                newAttribute.initializer().Accept(cloner);
82

    
83
                m_actionSystem.symbols().AddIdentifier(newAttribute);
84
        }
85

    
86
        public String getInstanceFunctionName(OoActionSystemInstance obj, FunctionIdentifier functionIdentifier)
87
        {
88
                final FunctionType functionType = (FunctionType) functionIdentifier.type();
89
                String objectName = "";
90
                switch(functionType.functionType()) {
91
                case Controllable:
92
                case Observable:
93
                        objectName = m_compressor.originalName(obj.Name);
94
                        break;
95
                case Internal:
96
                default:
97
                        objectName = obj.Name;
98
                }
99

    
100
                return String.format("%s_%s", objectName, functionIdentifier.tokenText());
101
        }
102

    
103
        private void DuplicateNamedAction(NamedActionIdentifier namedActionIdentifier,
104
                        OoActionSystemInstance obj, OoActionSystemType aType, ActionSystem m_actionSystem)
105
        {
106
                final NamedActionIdentifier newAction = new NamedActionIdentifier(namedActionIdentifier);
107
                final String actionName = getInstanceFunctionName(obj, namedActionIdentifier);
108
                newAction.SetTokenText(actionName);
109
                m_toReplace.putSafe(namedActionIdentifier, newAction);
110
                final OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
111
                newAction.Accept(cloner);
112

    
113
                m_actionSystem.symbols().AddIdentifier(newAction);
114
        }
115

    
116
        private void DuplicateMethod(MethodIdentifier methodIdentifier, OoActionSystemInstance obj,
117
                        OoActionSystemType aType, ActionSystem m_actionSystem)
118
        {
119
                final MethodIdentifier newMethod = new MethodIdentifier(methodIdentifier);
120
                final String methodName = getInstanceFunctionName(obj, methodIdentifier);
121
                newMethod.SetTokenText(methodName);
122
                m_toReplace.putSafe(methodIdentifier, newMethod);
123
                final Statement newBlock = newMethod.body().Clone();
124
                if (newBlock instanceof IScope)
125
                        ((IScope)newBlock).SetParentScope(newMethod);
126
                m_toReplace.putSafe(newMethod.body(), newBlock);
127
                newMethod.SetBody(newBlock);
128
                final OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
129
                newMethod.body().Accept(cloner);
130

    
131
                m_actionSystem.symbols().AddIdentifier(newMethod);
132
        }
133

    
134

    
135
        /*Duplicates the do-od block (incl. any do-od blocks of parent classes)*/
136
        private void DuplicateDoOdBlock(OoActionSystemInstance obj, OoActionSystemType aType, ActionSystem m_actionSystem, Block result)
137
        {
138
//                OoActionSystemType rootType = aType;
139
                Block block;
140
                while (aType != null)
141
                {
142
                        block = aType.doOdBlock();
143
                        if (block != null)
144
                        {
145
                                final Block clone = (Block)block.Clone();
146
                                m_toReplace.putSafe(block, clone);
147
                                clone.SetParentScope(result);
148
                                final OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
149
                                clone.Accept(cloner);
150
                                result.AddStatement(clone);
151
                        }
152
                        aType = aType.baseType();
153
                }
154
        }
155

    
156
        OoasCompilerHashMap<Object, Object> objectsdone = new OoasCompilerHashMap<Object, Object>();
157

    
158
        /// <summary>
159
        /// Generates an OoActionSystemType that is the instantiation of all the objects found in the System Assembling Block
160
        /// </summary>
161
        private void InstantiateObjects(ActionSystem m_actionSystem, MainModule mainModule, IdentifierList sysdescr, Block parent)
162
        {
163
                Block newBlock;
164
                switch (sysdescr.listType())
165
                {
166
                case nondeterministic:
167
                        newBlock = new NondetBlock(0, 0);
168
                        break;
169
                case prioritized:
170
                        newBlock = new PrioBlock(0, 0);
171
                        break;
172
                case seqential:
173
                        newBlock = new SeqBlock(0, 0);
174
                        break;
175

    
176
                case normal:
177
                default:
178
                        throw new NotImplementedException();
179
                }
180

    
181
                if (parent == null)
182
                        m_actionSystem.SetDoOdBlock(newBlock);
183
                else
184
                        parent.AddStatement(newBlock);
185

    
186
                for (final Identifier id: sysdescr.identifiers())
187
                {
188
                        Identifier ident = id;
189
                        while (ident.kind() == IdentifierKind.List && ((IdentifierList)ident).identifiers().size() == 1)
190
                        {
191
                                ident = ((IdentifierList)ident).identifiers().peekFirst();
192
                        }
193

    
194
                        if (ident.kind() == IdentifierKind.List)
195
                                InstantiateObjects(m_actionSystem, mainModule, (IdentifierList)ident, newBlock);
196
                        else
197
                        {
198
                                if (ident.kind() == IdentifierKind.TypeIdentifier &&
199
                                                ((TypeIdentifier)ident).type().kind() == TypeKind.OoActionSystemType)
200
                                {
201

    
202
                                        final OoActionSystemType aType = (OoActionSystemType)((TypeIdentifier)ident).type();
203
                                        objectsdone.putSafe(aType, m_actionSystem);
204

    
205

    
206
                                        Block NondetBlock = null; // holds parallel comp of all objects
207
                                        if (aType.doOdBlock() != null)
208
                                        {
209
                                                NondetBlock = new NondetBlock(0, 0);
210
                                                newBlock.AddStatement(NondetBlock);
211
                                        }
212

    
213

    
214
                                        for (final OoActionSystemInstance obj: aType.objects())
215
                                        {
216
                                                m_toReplace = new OoasCompilerHashMap<Object, Object>(objectsdone);
217
                                                addParentClassMappings(m_toReplace, aType, m_actionSystem);
218
                                                self = new SelfTypeIdentifier(obj.Name, aType, null);
219
                                                final SymbolTable table = aType.getAllSymbols();
220
                                                for (final Identifier x: table.symbolList())
221
                                                {
222
                                                        // resolve attributes first
223
                                                        if (x.kind() == IdentifierKind.AttributeIdentifier)
224
                                                                DuplicateAttribute((AttributeIdentifier)x, obj, aType, m_actionSystem);
225
                                                }
226
                                                for (final Identifier x: table.symbolList())
227
                                                {
228
                                                        // now do methods and other stuff
229
                                                        if (x.kind() == IdentifierKind.MethodIdentifier)
230
                                                                DuplicateMethod((MethodIdentifier)x, obj, aType, m_actionSystem);
231
                                                        else if (x.kind() == IdentifierKind.NamedActionIdentifier)
232
                                                                DuplicateNamedAction((NamedActionIdentifier)x, obj, aType, m_actionSystem);
233
                                                }
234
                                                // construct parallel composition of all the objects of one class.
235
                                                if (aType.doOdBlock() != null)
236
                                                {
237
                                                        DuplicateDoOdBlock(obj, aType, m_actionSystem, NondetBlock);
238
                                                }
239
                                        }
240

    
241
                                        // add an error, if a type does not get instantiated and the do-od block is filled..
242
                                        // !!!!!!!!!!!!!!! note, if new is also allowed in normal actions, this needs to be disabled (or become a warning) !!!!!!!!!!!!!!!!!!!!!!!!!!
243
                                        if (aType.objects().size() == 0 && aType.doOdBlock() != null)
244
                                        {
245
                                                m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier().line(), aType.identifier().column(),
246
                                                                String.format("Type '%s' is never instantiated but has a non-empty do-od block", aType.toString())));
247
                                        }
248
                                }
249
                                else
250
                                        throw new NotImplementedException();
251
                        }
252
                }
253
        }
254

    
255
        private void addParentClassMappings(OoasCompilerHashMap<Object, Object> m_toReplace, OoActionSystemType aType, ActionSystem m_actionSystem)
256
        {
257
                while (aType != null)
258
                {
259
                        if (!m_toReplace.containsKey(aType))
260
                                m_toReplace.putSafe(aType, m_actionSystem); // add base classes to mapping...
261
                        aType = aType.baseType();
262
                }
263
        }
264

    
265
        /// <summary>
266
        /// Adds those objects of types that are not found in the SAB.
267
        /// </summary>
268
        private void InstantiatePassiveObjects(ActionSystem m_actionSystem, MainModule mainModule)
269
        {
270
                for (final Identifier x: mainModule.symbolTable().symbolList())
271
                {
272
                        if (x.type().kind() == TypeKind.OoActionSystemType && !objectsdone.containsKey(x.type()))
273
                                if (((OoActionSystemType)x.type()).autoConstruction())
274
                                {
275
                                        final OoActionSystemType aType = (OoActionSystemType)x.type();
276
                                        m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier().line(), aType.identifier().column(),
277
                                                        String.format("Type '%s' marked autocons but omitted in system description!", aType.toString())));
278
                                }
279
                                else
280
                                {
281
                                        final OoActionSystemType aType = (OoActionSystemType)x.type();
282
                                        for (final OoActionSystemInstance obj: aType.objects())
283
                                        {
284
                                                m_toReplace = new OoasCompilerHashMap<Object, Object>(objectsdone);
285
                                                addParentClassMappings(m_toReplace, aType, m_actionSystem);
286
                                                self = new SelfTypeIdentifier(obj.Name, aType, null);
287
                                                final SymbolTable table = aType.getAllSymbols();
288
                                                for (final Identifier y: table.symbolList())
289
                                                {
290
                                                        // resolve attributes first
291
                                                        if (y.kind() == IdentifierKind.AttributeIdentifier)
292
                                                                DuplicateAttribute((AttributeIdentifier)y, obj, aType, m_actionSystem);
293
                                                }
294
                                                for (final Identifier y: table.symbolList())
295
                                                {
296
                                                        // now do methods
297
                                                        if (y.kind() == IdentifierKind.MethodIdentifier)
298
                                                                DuplicateMethod((MethodIdentifier)y, obj, aType, m_actionSystem);
299
                                                        //else if (y.kind == IdentifierKind.NamedActionIdentifier)
300
                                                        //    m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier.line, aType.identifier.column,
301
                                                        //        String.Format("Type '%s' has named actions but was omitted in system description!", aType.ToString())));
302
                                                }
303
                                                if (aType.doOdBlock() != null)
304
                                                        m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier().line(), aType.identifier().column(),
305
                                                                        String.format("Type '%s' has do-od block but was omitted in system description!", aType.toString())));
306
                                        }
307

    
308
                                }
309
                }
310
        }
311

    
312

    
313

    
314

    
315

    
316
        @Override
317
        public void visit(MainModule mainModule)
318
        {
319
                if (mainModule.systemDescription() == null)
320
                        return;
321

    
322
                // accept compression visitor
323
                if (m_compressor.compression() != LabelCompression.NoCompression)
324
                        mainModule.Accept(m_compressor);
325

    
326

    
327
                /* determine names of objects */
328
                mainModule.Accept(m_simulator);
329

    
330
                final boolean shortObjectNames = m_compressor.compression() == LabelCompression.All
331
                                                                          || m_compressor.compression() == LabelCompression.ActionsMethodsObjects;
332
                if (shortObjectNames) {
333
                        // compress object names
334
                        for (final OoActionSystemInstance instance: m_simulator.initialObjectWorkingSet()) {
335
                                instance.Name = m_compressor.labelFor(instance);
336
                        }
337
                }
338

    
339
                /* add information about all the objects to the AST */
340
                // mainModule.SetObjects(m_simulator.initialObjectWorkingSet);
341
                m_actionSystem = new ActionSystem();
342
                m_actionSystem.SetParentScope(mainModule);
343
                InstantiateObjects(m_actionSystem, mainModule, mainModule.systemDescription(), m_actionSystem.doOdBlock());
344
                InstantiatePassiveObjects(m_actionSystem, mainModule);
345

    
346
                mainModule.SetInstance(m_actionSystem);
347

    
348
                m_ParserState.mappingInformation = m_compressor.mappingInformation();
349
        }
350

    
351
        @Override
352
        public String toString()
353
        {
354
                return m_simulator.toString();
355
        }
356

    
357

    
358
        public OoaObjectInstantiationVisitor(ParserState aState, LabelCompression compression)
359
        {
360
                super (aState);
361
                m_simulator = new JavaInitVisitor(aState);
362
                m_compressor = new OoaIdentifierCompressVisitor(aState, compression);
363
        }
364

    
365
}