Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / visitors / OoaObjectInstantiationVisitor.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.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
                final OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
80
                newAttribute.initializer().Accept(cloner);
81

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

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

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

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

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

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

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

    
133

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

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

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

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

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

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

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

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

    
204

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

    
212

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

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

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

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

    
307
                                }
308
                }
309
        }
310

    
311

    
312

    
313

    
314

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

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

    
325

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

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

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

    
345
                mainModule.SetInstance(m_actionSystem);
346

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

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

    
356

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

    
364
}