Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / visitors / OoaDeepCloneVisitor.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 java.util.ArrayList;
31
import java.util.Arrays;
32
import java.util.HashMap;
33
import java.util.List;
34
import java.util.ListIterator;
35

    
36
import org.momut.ooas.ast.IScope;
37
import org.momut.ooas.ast.expressions.AccessExpression;
38
import org.momut.ooas.ast.expressions.BinaryOperator;
39
import org.momut.ooas.ast.expressions.CallExpression;
40
import org.momut.ooas.ast.expressions.ExistsQuantifier;
41
import org.momut.ooas.ast.expressions.Expression;
42
import org.momut.ooas.ast.expressions.ForallQuantifier;
43
import org.momut.ooas.ast.expressions.IdentifierExpression;
44
import org.momut.ooas.ast.expressions.ListConstructor;
45
import org.momut.ooas.ast.expressions.MapConstructor;
46
import org.momut.ooas.ast.expressions.ObjectConstructor;
47
import org.momut.ooas.ast.expressions.QValConstructor;
48
import org.momut.ooas.ast.expressions.Quantifier;
49
import org.momut.ooas.ast.expressions.SetConstructor;
50
import org.momut.ooas.ast.expressions.TernaryOperator;
51
import org.momut.ooas.ast.expressions.TupleConstructor;
52
import org.momut.ooas.ast.expressions.TupleMapAccessExpression;
53
import org.momut.ooas.ast.expressions.TypeExpression;
54
import org.momut.ooas.ast.expressions.UnaryOperator;
55
import org.momut.ooas.ast.expressions.UnresolvedIdentifierExpression;
56
import org.momut.ooas.ast.expressions.ValueExpression;
57
import org.momut.ooas.ast.identifiers.AttributeIdentifier;
58
import org.momut.ooas.ast.identifiers.EnumIdentifier;
59
import org.momut.ooas.ast.identifiers.ExpressionVariableIdentifier;
60
import org.momut.ooas.ast.identifiers.Identifier;
61
import org.momut.ooas.ast.identifiers.IdentifierKind;
62
import org.momut.ooas.ast.identifiers.LandmarkIdentifier;
63
import org.momut.ooas.ast.identifiers.LocalVariableIdentifier;
64
import org.momut.ooas.ast.identifiers.MainModule;
65
import org.momut.ooas.ast.identifiers.MethodIdentifier;
66
import org.momut.ooas.ast.identifiers.Module;
67
import org.momut.ooas.ast.identifiers.NamedActionIdentifier;
68
import org.momut.ooas.ast.identifiers.NondetIdentifierList;
69
import org.momut.ooas.ast.identifiers.ParameterIdentifier;
70
import org.momut.ooas.ast.identifiers.PrioIdentifierList;
71
import org.momut.ooas.ast.identifiers.SeqIdentifierList;
72
import org.momut.ooas.ast.identifiers.TypeIdentifier;
73
import org.momut.ooas.ast.identifiers.UnspecIdentifierList;
74
import org.momut.ooas.ast.statements.AbortStatement;
75
import org.momut.ooas.ast.statements.Assignment;
76
import org.momut.ooas.ast.statements.Block;
77
import org.momut.ooas.ast.statements.Call;
78
import org.momut.ooas.ast.statements.GuardedCommand;
79
import org.momut.ooas.ast.statements.KillStatement;
80
import org.momut.ooas.ast.statements.NondetBlock;
81
import org.momut.ooas.ast.statements.PrioBlock;
82
import org.momut.ooas.ast.statements.QualitativeConstraintStatement;
83
import org.momut.ooas.ast.statements.SeqBlock;
84
import org.momut.ooas.ast.statements.SkipStatement;
85
import org.momut.ooas.ast.statements.Statement;
86
import org.momut.ooas.ast.types.AnyType;
87
import org.momut.ooas.ast.types.BoolType;
88
import org.momut.ooas.ast.types.CharType;
89
import org.momut.ooas.ast.types.EnumType;
90
import org.momut.ooas.ast.types.FloatType;
91
import org.momut.ooas.ast.types.FunctionType;
92
import org.momut.ooas.ast.types.IntType;
93
import org.momut.ooas.ast.types.ListType;
94
import org.momut.ooas.ast.types.MapType;
95
import org.momut.ooas.ast.types.NullType;
96
import org.momut.ooas.ast.types.OoActionSystemType;
97
import org.momut.ooas.ast.types.OpaqueType;
98
import org.momut.ooas.ast.types.QrType;
99
import org.momut.ooas.ast.types.TupleType;
100
import org.momut.ooas.parser.SymbolTable;
101
import org.momut.ooas.utils.OoasCompilerHashMap;
102
import org.momut.ooas.utils.exceptions.ArgumentException;
103
import org.momut.ooas.utils.exceptions.NotImplementedException;
104
import org.momut.ooas.utils.exceptions.InternalCompilerException;
105

    
106
public final class OoaDeepCloneVisitor extends OoaCompleteAstTraversalVisitor
107
{
108

    
109
        OoasCompilerHashMap<Object, Object> mapping;
110
        Identifier selfreplacement;
111

    
112
        public boolean quantifierState = false;
113

    
114
        /* we do not clone types */
115
        @Override
116
        public /*override*/ void visit(AnyType anyType)
117
        { throw new NotImplementedException(); }
118
        @Override
119
        public /*override*/ void visit(BoolType boolType)
120
        { throw new NotImplementedException(); }
121
        @Override
122
        public /*override*/ void visit(CharType charType)
123
        { throw new NotImplementedException(); }
124
        @Override
125
        public /*override*/ void visit(EnumType enumType)
126
        { throw new NotImplementedException(); }
127
        @Override
128
        public /*override*/ void visit(FloatType floatType)
129
        { throw new NotImplementedException(); }
130
        @Override
131
        public /*override*/ void visit(FunctionType functionType)
132
        { throw new NotImplementedException(); }
133
        @Override
134
        public /*override*/ void visit(IntType intType)
135
        { throw new NotImplementedException(); }
136
        @Override
137
        public /*override*/ void visit(ListType listType)
138
        { throw new NotImplementedException(); }
139
        @Override
140
        public /*override*/ void visit(MapType mapType)
141
        { throw new NotImplementedException(); }
142
        @Override
143
        public /*override*/ void visit(NullType nullType)
144
        { throw new NotImplementedException(); }
145
        @Override
146
        public /*override*/ void visit(OoActionSystemType ooActionSystemType)
147
        { throw new NotImplementedException(); }
148
        @Override
149
        public /*override*/ void visit(TupleType tupleType)
150
        { throw new NotImplementedException(); }
151
        @Override
152
        public /*override*/ void visit(EnumIdentifier enumIdentifier)
153
        { throw new NotImplementedException(); }
154
        @Override
155
        public /*override*/ void visit(LandmarkIdentifier landmarkIdentifier)
156
        { throw new NotImplementedException(); }
157
        @Override
158
        public /*override*/ void visit(ExpressionVariableIdentifier expressionVariableIdentifier)
159
        { throw new NotImplementedException(); }
160

    
161

    
162
        @Override
163
        public /*override*/ void visit(LocalVariableIdentifier localVariableIdentifier)
164
        {
165
                throw new NotImplementedException();
166
        }
167

    
168
        @Override
169
        public /*override*/ void visit(MainModule mainModule)
170
        {
171
                throw new NotImplementedException();
172
        }
173

    
174

    
175
        @Override
176
        public /*override*/ void visit(MapConstructor mapConstructor)
177
        {
178
                throw new NotImplementedException();
179
        }
180

    
181
        @Override
182
        public /*override*/ void visit(MethodIdentifier methodIdentifier)
183
        {
184
                throw new NotImplementedException();
185
        }
186

    
187
        @Override
188
        public /*override*/ void visit(NamedActionIdentifier namedActionIdentifier)
189
        {
190
                final Statement newBlock = SClone(namedActionIdentifier.body());
191
                namedActionIdentifier.SetBody(newBlock);
192
                // we do not clone the parameters..
193
        }
194

    
195
        @Override
196
        public /*override*/ void visit(Module module)
197
        {
198
                throw new NotImplementedException();
199
        }
200

    
201
        @Override
202
        public /*override*/ void visit(NondetIdentifierList nondetIdentifierList)
203
        {
204
                throw new NotImplementedException();
205
        }
206

    
207

    
208
        @Override
209
        public /*override*/ void visit(OpaqueType opaqueType)
210
        {
211
                throw new NotImplementedException(); // must not happen
212
        }
213

    
214
        @Override
215
        public /*override*/ void visit(ParameterIdentifier parameterIdentifier)
216
        {
217
                throw new NotImplementedException();
218
        }
219

    
220
        @Override
221
        public /*override*/ void visit(PrioIdentifierList prioIdentifierList)
222
        {
223
                throw new NotImplementedException();
224
        }
225

    
226
        @Override
227
        public /*override*/ void visit(QrType qrType)
228
        {
229
                throw new NotImplementedException();
230
        }
231

    
232

    
233

    
234
        @Override
235
        public /*override*/ void visit(ObjectConstructor objectConstructor)
236
        {
237
                //base.visit(objectConstructor);
238
        }
239

    
240
        private void UpdateScope(IScope aScope)
241
        {
242
                if (aScope.GetParentScope() != null && !mapping.containsKey(aScope.GetParentScope()))
243
                        throw new ArgumentException();
244
                else if (aScope.GetParentScope() != null)
245
                {
246
                        aScope.SetParentScope((IScope)mapping.get(aScope.GetParentScope()));
247
                }
248
        }
249

    
250
        private void CheckScope(IScope aScope) {
251
                if (aScope.GetParentScope() == null)
252
                        return;
253
                if (mapping.containsKey(aScope.GetParentScope()))
254
                        throw new InternalCompilerException("Internal Error. Scope check failed.");
255
        }
256

    
257
        private Expression EClone(Expression anExpr)
258
        {
259
                Expression result = null;
260
                if (anExpr != null)
261
                {
262
                        result = anExpr.Clone();
263

    
264
                        if (anExpr instanceof IScope)
265
                        {
266
                                mapping.putSafe(anExpr, result);
267
                                UpdateScope((IScope)result);
268
                        }
269

    
270
                        result.Accept(this);
271
                }
272
                return result;
273
        }
274

    
275
        private Statement SClone(Statement aStatement)
276
        {
277
                Statement result = null;
278
                if (aStatement != null)
279
                {
280
                        result = aStatement.Clone();
281

    
282
                        if (aStatement instanceof IScope)
283
                        {
284
                                mapping.putSafe(aStatement, result);
285
                                UpdateScope((IScope)result);
286
                        }
287

    
288
                        result.Accept(this);
289
                }
290
                return result;
291
        }
292

    
293
        // clones symbols found in symbol table
294
        private void SymTabClone(SymbolTable aTable)
295
        {
296
                if (aTable != null && aTable.symbolList().size() > 0)
297
                {
298
                        final List<Identifier> newList = new ArrayList<Identifier>();
299
                        for (final Identifier x: aTable.symbolList())
300
                        {
301
                                if (!mapping.containsKey(x))
302
                                {
303
                                        final Identifier newid = x.Clone();
304
                                        newList.add(newid);
305
                                        mapping.putSafe(x, newid);
306
                                }
307
                                else
308
                                        newList.add((Identifier)mapping.get(x));
309
                        }
310
                        aTable.SetSymbolList(newList);
311
                }
312
        }
313

    
314

    
315
        private void cloneExpressionList(ListIterator<Expression> anElem)
316
        {
317
                while (anElem.hasNext())
318
                {
319
                        final Expression clone = EClone(anElem.next());
320
                        anElem.remove();
321
                        anElem.add(clone);
322
                }
323
        }
324

    
325

    
326
        /*no need to clone leafs (they are already cloned and a shallow copy is sufficient*/
327
        @Override
328
        public /*override*/ void visit(AbortStatement abortStatement)
329
        { }
330
        @Override
331
        public /*override*/ <T> void visit(ValueExpression<T> valueExpression)
332
        { }
333

    
334

    
335
        /*clone a block*/
336
        public void cloneBlock(Block aBlock)
337
        {
338
                SymTabClone(aBlock.symbols());
339
                final ListIterator<Statement> stmnt = aBlock.statements().listIterator();
340
                while (stmnt.hasNext())
341
                {
342
                        final Statement clone = SClone(stmnt.next());
343
                        stmnt.remove();
344
                        stmnt.add(clone);
345
                }
346
        }
347
        @Override
348
        public /*override*/ void visit(NondetBlock nondetBlock)
349
        {
350
                cloneBlock(nondetBlock);
351
        }
352
        @Override
353
        public /*override*/ void visit(SeqBlock seqBlock)
354
        {
355
                seqBlock.SetFilter(EClone(seqBlock.filter()));
356
                cloneBlock(seqBlock);
357
        }
358
        @Override
359
        public /*override*/ void visit(PrioBlock prioBlock)
360
        {
361
                cloneBlock(prioBlock);
362
        }
363

    
364
        @Override
365
        public /*override*/ void visit(AccessExpression accessExpression)
366
        {
367
                visit((BinaryOperator)accessExpression);
368
        }
369
        @Override
370
        public /*override*/ void visit(BinaryOperator binaryOperator)
371
        {
372
                final Expression left = EClone(binaryOperator.left());
373
                final Expression right = EClone(binaryOperator.right());
374
                binaryOperator.SetLeftChild(left);
375
                binaryOperator.SetRightChild(right);
376
        }
377

    
378
        @Override
379
        public /*override*/ void visit(Assignment assignment)
380
        {
381
                SymTabClone(assignment.symbols());
382
                cloneExpressionList(assignment.places().listIterator());
383
                cloneExpressionList(assignment.values().listIterator());
384
                assignment.SetNondetExpression(EClone(assignment.nondetExpression()));
385
                CheckScope(assignment);
386
        }
387

    
388
        @Override
389
        public /*override*/ void visit(AttributeIdentifier attributeIdentifier)
390
        {
391
                final Expression initializer = EClone(attributeIdentifier.initializer());
392
                attributeIdentifier.SetInitializer(initializer);
393
        }
394
        @Override
395
        public /*override*/ void visit(Call call)
396
        {
397
                final Expression cExpr = EClone(call.callExpression());
398
                call.SetCallExpression(cExpr);
399
        }
400

    
401
        @Override
402
        public /*override*/ void visit(CallExpression callExpression)
403
        {
404
                final ArrayList<Expression> newargs = new ArrayList<Expression>();
405
                for (final Expression x: callExpression.arguments())
406
                {
407
                        newargs.add(EClone(x));
408
                }
409
                callExpression.SetArguments(newargs);
410

    
411
                visit((UnaryOperator)callExpression);
412
        }
413

    
414
        public void CloneQuantifier(Quantifier qf)
415
        {
416
                SymTabClone(qf.symbols());
417
                final boolean oldQunatifierState = quantifierState;
418
                quantifierState = true;
419
                visit(qf);
420
                quantifierState = oldQunatifierState;
421
        }
422
        @Override
423
        public /*override*/ void visit(ExistsQuantifier quantifier)
424
        {
425
                CloneQuantifier(quantifier);
426
        }
427
        @Override
428
        public /*override*/ void visit(ForallQuantifier quantifier)
429
        {
430
                CloneQuantifier(quantifier);
431
        }
432

    
433

    
434

    
435

    
436
        @Override
437
        public /*override*/ void visit(GuardedCommand guardedCommand)
438
        {
439
                final Statement newblock = SClone(guardedCommand.body());
440
                final Expression newguard = EClone(guardedCommand.guard());
441
                guardedCommand.SetBody(newblock);
442
                guardedCommand.SetGuard(newguard);
443
        }
444

    
445
        @Override
446
        public /*override*/ void visit(IdentifierExpression identifierExpression)
447
        {
448

    
449
                if (identifierExpression.isSelf())
450
                {
451
                        /*if (quantifierState) //FIXXME
452
            {
453
                if (!selfreplacement.tokenText.StartsWith("attr"))
454
                {
455
                    String oldTokenText = selfreplacement.tokenText;
456
                    selfreplacement.SetTokenText("attr____model_root_" + selfreplacement.tokenText);
457
                    identifierExpression.SetIdentifier(selfreplacement);
458
                    selfreplacement.SetTokenText(oldTokenText);
459
                }
460
            }
461
            else
462
                         */
463
                        identifierExpression.SetIdentifier(selfreplacement);
464

    
465

    
466
                }
467
                else if (mapping.containsKey(identifierExpression.identifier())
468
                                && identifierExpression.identifier().kind() != IdentifierKind.MethodIdentifier)
469

    
470
                        /* we do NOT replace method calls here, since they are prefixed by self if it's a
471
                         * method in the current object or by some field/method access if it's another
472
                         * object.
473
                         */
474
                        identifierExpression.SetIdentifier((Identifier)mapping.get(identifierExpression.identifier()));
475

    
476
        }
477

    
478
        @Override
479
        public /*override*/ void visit(KillStatement killStatement)
480
        {
481
                if (mapping.containsKey(killStatement.someOne))
482
                        killStatement.SetIdentifier((Identifier)mapping.get(killStatement.someOne));
483
        }
484

    
485

    
486
        @Override
487
        public /*override*/ void visit(ListConstructor listConstructor)
488
        {
489
                SymTabClone(listConstructor.comprehensionVariables());
490

    
491
                final ArrayList<Expression> newelems = new ArrayList<Expression>();
492
                for (final Expression x: listConstructor.elements())
493
                        newelems.add(EClone(x));
494

    
495
                listConstructor.SetElements(newelems);
496
                listConstructor.SetComprehension(EClone(listConstructor.comprehension()));
497
        }
498

    
499
        @Override
500
        public /*override*/ void visit(QualitativeConstraintStatement qalitativeConstraintStatement)
501
        {
502
                if (qalitativeConstraintStatement.variable0() != null && mapping.containsKey(qalitativeConstraintStatement.variable0()))
503
                        qalitativeConstraintStatement.SetVariable0((Identifier)mapping.get(qalitativeConstraintStatement.variable0()));
504
                if (qalitativeConstraintStatement.variable1() != null && mapping.containsKey(qalitativeConstraintStatement.variable1()))
505
                        qalitativeConstraintStatement.SetVariable1((Identifier)mapping.get(qalitativeConstraintStatement.variable1()));
506
                if (qalitativeConstraintStatement.variable2() != null && mapping.containsKey(qalitativeConstraintStatement.variable2()))
507
                        qalitativeConstraintStatement.SetVariable2((Identifier)mapping.get(qalitativeConstraintStatement.variable2()));
508
        }
509

    
510

    
511
        @Override
512
        public /*override*/ void visit(QValConstructor qValConstructor)
513
        {
514
                final List<Expression> values = Arrays.asList(qValConstructor.value());
515
                for (int i = 0; i < values.size(); i++)
516
                        qValConstructor.value()[i] = EClone(values.get(i));
517
        }
518

    
519
        @Override
520
        public /*override*/ void visit(SeqIdentifierList seqIdentifierList)
521
        {
522
                throw new NotImplementedException();
523
        }
524

    
525

    
526
        @Override
527
        public /*override*/ void visit(SetConstructor setConstructor)
528
        {
529
                SymTabClone(setConstructor.comprehensionVariables());
530
                final ArrayList<Expression> newelems = new ArrayList<Expression>();
531
                for (final Expression x: setConstructor.items())
532
                        newelems.add(EClone(x));
533

    
534
                setConstructor.SetItems(newelems);
535
                setConstructor.SetComprehension(EClone(setConstructor.comprehension()));
536
        }
537

    
538

    
539
        @Override
540
        public /*override*/ void visit(SkipStatement skipStatement)
541
        { }
542

    
543
        @Override
544
        public /*override*/ void visit(TernaryOperator ternaryOperator)
545
        {
546
                ternaryOperator.SetLeftChild(EClone(ternaryOperator.left()));
547
                ternaryOperator.SetMidChild(EClone(ternaryOperator.mid()));
548
                ternaryOperator.SetRightChild(EClone(ternaryOperator.right()));
549
        }
550

    
551
        @Override
552
        public /*override*/ void visit(TupleConstructor tupleConstructor)
553
        {
554
                final ArrayList<Expression> values = new ArrayList<Expression>();
555
                for (final Expression x: tupleConstructor.values())
556
                        values.add(EClone(x));
557
                tupleConstructor.SetTupleValues(values);
558
        }
559

    
560
        @Override
561
        public /*override*/ void visit(TupleMapAccessExpression tupleMapAccessExpression)
562
        {
563
                tupleMapAccessExpression.SetArgument(EClone(tupleMapAccessExpression.argument()));
564
                visit((UnaryOperator)tupleMapAccessExpression);
565
        }
566

    
567
        @Override
568
        public /*override*/ void visit(TypeExpression typeExpression)
569
        { /*we do not clone types*/ }
570

    
571

    
572
        @Override
573
        public /*override*/ void visit(TypeIdentifier typeIdentifier)
574
        {
575
                throw new NotImplementedException();
576
        }
577

    
578
        @Override
579
        public /*override*/ void visit(UnaryOperator unaryOperator)
580
        {
581
                final Expression child = EClone(unaryOperator.child());
582
                unaryOperator.SetChild(child);
583
        }
584

    
585

    
586
        @Override
587
        public /*override*/ void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
588
        {
589
                throw new NotImplementedException(); // must not occur
590
        }
591

    
592
        @Override
593
        public /*override*/ void visit(UnspecIdentifierList unspecIdentifierList)
594
        {
595
                throw new NotImplementedException();
596
        }
597

    
598
        public OoaDeepCloneVisitor(HashMap<Object, Object> initMapping, Identifier selfreplace)
599
        {
600
                super (null);
601
                mapping = new OoasCompilerHashMap<Object, Object>(initMapping);
602
                selfreplacement = selfreplace;
603
        }
604
}