Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / ast / types / UlyssesType.java @ 6

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.ast.types;
29

    
30
import java.util.Iterator;
31

    
32
import org.momut.ooas.ast.AstNode;
33
import org.momut.ooas.ast.AstNodeTypeEnum;
34
import org.momut.ooas.ast.IAst;
35
import org.momut.ooas.ast.IAstVisitor;
36
import org.momut.ooas.ast.identifiers.TypeIdentifier;
37
import org.momut.ooas.utils.exceptions.ArgumentException;
38
import org.momut.ooas.utils.exceptions.NotImplementedException;
39
import org.momut.ooas.utils.exceptions.OoasCompilerRuntimeException;
40

    
41
public abstract class UlyssesType extends AstNode implements IAst
42
{
43
        private String m_origAnonName;
44
        protected TypeKind m_kind;
45
        protected TypeIdentifier m_identifier;
46
        protected int m_hash;
47
        //    protected long TimeStamp = DateTime.Now.Ticks;
48

    
49

    
50
        public TypeKind kind() { return m_kind; }
51

    
52
        public TypeIdentifier identifier() {
53
                synchronized(this) {
54
                        if (m_identifier == null)
55
                                SetupAnonymousName();
56
                }
57
                return m_identifier;
58
        }
59

    
60
        public boolean isAnonymousType() {
61
                final String anonName = AnonymousName();
62
                if (!m_origAnonName.equals(anonName))
63
                        throw new OoasCompilerRuntimeException("Internal Error: Anonymous Name changed from '%s' to '%s'.", m_origAnonName, anonName);
64
                return anonName.equals(m_identifier.tokenText());
65
        }
66

    
67
        protected UlyssesType(TypeKind aKind, TypeIdentifier anIdentifier)
68
        {
69
                m_kind = aKind;
70
                m_identifier = anIdentifier;
71
                m_hash = aKind.toString().hashCode(); //Enum.GetName(typeof(TypeKind), aKind).GetHashCode();
72
        }
73

    
74
        @Override
75
        public /*override*/ String toString()
76
        {
77
                return identifier().tokenText();
78
        }
79

    
80
        public /*virtual*/ String AnonymousName()
81
        {
82
                throw new NotImplementedException();
83
        }
84

    
85

    
86
        public void SetTypeIdentifier(TypeIdentifier anId)
87
        {
88
                m_identifier = anId;
89
        }
90

    
91
        public void SetupAnonymousName()
92
        {
93
                if (m_identifier == null)
94
                {
95
                        final String anonymousName = this.AnonymousName();
96
                        m_identifier = new TypeIdentifier(anonymousName, this, null);
97
                        m_origAnonName = anonymousName;
98
                }
99
        }
100

    
101

    
102
        @Override
103
        public AstNodeTypeEnum nodeType() { return AstNodeTypeEnum.type; }
104

    
105
        @Override
106
        public void Accept(IAstVisitor visitor)
107
        {
108
                throw new NotImplementedException();
109
        }
110

    
111

    
112

    
113
        public boolean IsNumeric()
114
        {
115
                final Object o = this;
116
                return (m_kind == TypeKind.IntType) ||
117
                                (m_kind == TypeKind.FloatType) ||
118
                                (m_kind == TypeKind.EnumeratedType && o instanceof ValuedEnumType);
119
        }
120

    
121
        public boolean IsQualitative()
122
        {
123
                return (m_kind == TypeKind.QrType);
124
        }
125

    
126
        /**
127
         * returns the number of unique values of the type (2 for bool, etc..)
128
         */
129
        public int valueCount() {
130
                throw new NotImplementedException(); // must be overridden by child
131
        }
132

    
133
        public static String High(UlyssesType atype)
134
        {
135
                switch (atype.kind())
136
                {
137
                        case BoolType:
138
                                return "1";
139
                        case EnumeratedType:
140
                                return Integer.toString((((EnumType)atype).listOfEnumSymbols().size() - 1));
141
                        case IntType:
142
                                return Integer.toString(((IntType)atype).rangeHigh());
143
                        case FloatType:
144
                                return Double.toString(((FloatType)atype).high());
145
//                        case TypeKind.QrType:
146
//                                return (((QrType)atype).landmarks.Count - 1).ToString();
147
                        default:
148
                                throw new NotImplementedException();
149
                }
150
        }
151

    
152
        public static String Low(UlyssesType atype)
153
        {
154
                switch (atype.kind())
155
                {
156
                        case BoolType:
157
                                return "0";
158
                        case EnumeratedType:
159
                                return "0";
160
                        case IntType:
161
                                return Integer.toString(((IntType)atype).rangeLow());
162
                        case FloatType:
163
                                return Double.toString(((FloatType)atype).low());
164
//                        case TypeKind.QrType:
165
//                                return "0";
166
                        default:
167
                                throw new NotImplementedException();
168
                }
169
        }
170

    
171

    
172
        /// <summary>
173
        ///  Returns a cover for two types (if possible).
174
        ///  note the cover type for two ints, floats, etc. will have max/min values
175
        ///  that reflect the maximum of the two operands.
176
        /// </summary>
177

    
178
        public static UlyssesType CoverType(UlyssesType type1, UlyssesType type2)
179
        {
180
                /*first some sanity checks*/
181
                if (type1 == null)
182
                        throw new ArgumentException("type1 null");
183
                if (type2 == null)
184
                        throw new ArgumentException("type2 null");
185

    
186
                if (type1.kind() == TypeKind.OpaqueType)
187
                        throw new ArgumentException("type1 opaque type");
188
                if (type2.kind() == TypeKind.OpaqueType)
189
                        throw new ArgumentException("type2 opaque type");
190

    
191
                if (type1 == type2)
192
                        return type1;
193
                if (UlyssesType.TypeEqual(type1, type2))
194
                        return type1;
195

    
196
                final TypeKind tk1 = type1.kind();
197
                final TypeKind tk2 = type2.kind();
198

    
199

    
200

    
201
                if (tk1 != tk2)
202
                {
203
                        // the only notion we support here is int->float and valenum -> int
204
                        if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
205
                                        && (tk1 == TypeKind.FloatType || tk2 == TypeKind.FloatType))
206
                        {
207
                                final IntType aInt = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
208
                                final FloatType aFloat = tk1 == TypeKind.IntType ? (FloatType)type2 : (FloatType)type1;
209

    
210
                                final double low = aInt.rangeLow() < aFloat.low() ? (double)aInt.rangeLow() : aFloat.low();
211
                                final double high = aInt.rangeHigh() < aFloat.high() ? aFloat.high() : (double)aInt.rangeHigh();
212
                                final double precision = aFloat.precision() > 1 ? 1.0 : aFloat.precision();
213

    
214
                                return new FloatType(low, high, precision, null);
215

    
216
                        }
217
                        else if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
218
                                        && (tk1 == TypeKind.EnumeratedType || tk2 == TypeKind.EnumeratedType))
219
                        {
220
                                final IntType intt1 = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
221
                                final EnumType anEnum = tk1 == TypeKind.IntType ? (EnumType)type2 : (EnumType)type1;
222

    
223
                                if (anEnum instanceof ValuedEnumType)
224
                                {
225
                                        final IntType intt2 = ((ValuedEnumType)anEnum).getIntType();
226
                                        final int low = intt1.rangeLow() < intt2.rangeLow() ? intt1.rangeLow() : intt2.rangeLow();
227
                                        final int high = intt1.rangeHigh() > intt2.rangeHigh() ? intt1.rangeHigh() : intt2.rangeHigh();
228
                                        return new IntType(low, high, null);
229
                                }
230
                                else
231
                                        return null;
232
                        }
233
                        else if (tk1 == TypeKind.Any || tk2 == TypeKind.Any)
234
                        {
235
                                final AnyType freeVar = tk1 == TypeKind.Any ? (AnyType)type1 : (AnyType)type2;
236
                                final UlyssesType fixedType = tk1 == TypeKind.Any ? type2 : type1;
237
                                final UlyssesType newcover = freeVar.VariableIdentifier().type().kind() == TypeKind.Any
238
                                                ? fixedType : CoverType(fixedType, freeVar.VariableIdentifier().type());
239
                                freeVar.VariableIdentifier().SetType(newcover);
240
                                return newcover;
241
                        }
242
                        else if (tk1 == TypeKind.OoActionSystemType && tk2 == TypeKind.Null)
243
                        {
244
                                return type1;
245
                        }
246
                        else if (tk2 == TypeKind.OoActionSystemType && tk1 == TypeKind.Null)
247
                        {
248
                                return type2;
249
                        }
250

    
251
                        else
252
                                return null;
253
                }
254
                else
255
                {
256
                        switch (tk1)
257
                        {
258
                                case Any:
259
                                        return type1;
260

    
261
                                case IntType:
262
                                        final IntType intt1 = (IntType)type1;
263
                                        final IntType intt2 = (IntType)type2;
264
                                        final int low = intt1.rangeLow() < intt2.rangeLow() ? intt1.rangeLow() : intt2.rangeLow();
265
                                        final int high = intt1.rangeHigh() > intt2.rangeHigh() ? intt1.rangeHigh() : intt2.rangeHigh();
266
                                        return new IntType(low, high, null);
267
                                case BoolType:
268
                                        return type1;
269
                                case FloatType:
270
                                        final FloatType floatt1 = (FloatType)type1;
271
                                        final FloatType floatt2 = (FloatType)type2;
272
                                        final double flow = floatt1.low() < floatt2.low() ? floatt1.low() : floatt2.low();
273
                                        final double fhigh = floatt1.high() > floatt2.high() ? floatt1.high() : floatt2.high();
274
                                        final double fprec = floatt1.precision() < floatt2.precision() ? floatt1.precision() : floatt2.precision();
275
                                        return new FloatType(flow, fhigh, fprec, null);
276
                                case EnumeratedType:
277
                                        return null;
278
                                case ListType:
279
                                        final ListType listt1 = (ListType)type1;
280
                                        final ListType listt2 = (ListType)type2;
281
                                        int maxelems = listt1.maxNumberOfElements() > listt2.maxNumberOfElements() ?
282
                                                listt1.maxNumberOfElements() : listt2.maxNumberOfElements();
283
                                        // empty lists lack type, so take the other one
284
                                        if ((listt1.innerType().kind() == TypeKind.Null) && (listt2.innerType().kind() != TypeKind.Null))
285
                                                return listt2;
286
                                        else if ((listt2.innerType().kind() == TypeKind.Null) && (listt1.innerType().kind() != TypeKind.Null))
287
                                                return listt1;
288
                                        else if (listt1.innerType().kind() == TypeKind.Null && listt2.innerType().kind() == TypeKind.Null)
289
                                                return listt1;
290
                                        else
291
                                        {
292
                                                final UlyssesType subtype = UlyssesType.CoverType(listt1.innerType(), listt2.innerType());
293
                                                if (subtype != null)
294
                                                        return new ListType(subtype, maxelems, null);
295
                                                else
296
                                                        return null;
297
                                        }
298
                                case MapType:
299
                                        final MapType mapt1 = (MapType)type1;
300
                                        final MapType mapt2 = (MapType)type2;
301
                                        // empty maps lack type, so take the other one.
302
                                        if ((mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null)
303
                                           && (mapt2.fromType().kind() != TypeKind.Null && mapt2.toType().kind() != TypeKind.Null))
304
                                                return mapt2;
305
                                        else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null)
306
                                           && (mapt1.fromType().kind() != TypeKind.Null && mapt1.toType().kind() != TypeKind.Null))
307
                                                return mapt1;
308
                                        else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null)
309
                                           && (mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null))
310
                                                return mapt1;
311
                                        else
312
                                        {
313
                                                final UlyssesType sub1 = UlyssesType.CoverType(mapt1.fromType(), mapt2.fromType());
314
                                                final UlyssesType sub2 = UlyssesType.CoverType(mapt2.toType(), mapt2.toType());
315
                                                maxelems = mapt1.maxNumberOfElements() > mapt2.maxNumberOfElements() ?
316
                                                        mapt1.maxNumberOfElements() : mapt2.maxNumberOfElements();
317
                                                if (sub1 != null && sub2 != null)
318
                                                        return new MapType(sub1, sub2, maxelems, null);
319
                                                else
320
                                                        return null;
321
                                        }
322
                                case QrType:
323
                                        return null; /*if refs are equal, we do not reach this statement! see above..*/
324
                                case TupleType:
325
                                        final TupleType tuplet1 = (TupleType)type1;
326
                                        final TupleType tuplet2 = (TupleType)type2;
327
                                        final TupleType result = new TupleType(null);
328
                                        final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator();
329
                                        final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator();
330
                                        while (innert1.hasNext())
331
                                        {
332
                                                final UlyssesType newinner = UlyssesType.CoverType(innert1.next(), innert2.next());
333
                                                if (newinner == null)
334
                                                        return null;
335
                                                result.AddType(newinner);
336
                                        }
337
                                        return result;
338
                                case OoActionSystemType:
339
                                        if (type1.kind() == TypeKind.Null && type2.kind() != TypeKind.Null)
340
                                                return type2;
341
                                        else if (type2.kind() == TypeKind.Null && type1.kind() != TypeKind.Null)
342
                                                return type1;
343
                                        else if (type1.kind() == TypeKind.Null && type2.kind() == TypeKind.Null)
344
                                                return type2;
345
                                        else if (type1 == type2) // ref equals!
346
                                                return type1;
347
                                        else
348
                                                return ClassBaseType((OoActionSystemType)type1, (OoActionSystemType)type2);
349
                                case OpaqueType:
350
                                        assert(false);
351
                                        return null;
352
                                default:
353
                                        throw new NotImplementedException();
354
                        }
355
                }
356
        }
357

    
358
        private static UlyssesType ClassBaseType(OoActionSystemType type1, OoActionSystemType type2)
359
        {
360
                // this is rather inefficient.. should be done differently
361
                final OoActionSystemType typea = type1;
362
                final OoActionSystemType typeb = type2;
363
                OoActionSystemType basea = type1;
364
                OoActionSystemType baseb = type2;
365
                while (basea != null)
366
                {
367
                        if (basea == typeb)  // ref equals
368
                                return basea;
369
                        basea = basea.baseType();
370
                }
371
                while (baseb != null)
372
                {
373
                        if (baseb == typea) // ref equals
374
                                return baseb;
375
                        baseb = baseb.baseType();
376
                }
377
                return null;
378
        }
379

    
380
        public static boolean FirstTypeLessRange(UlyssesType type1, UlyssesType type2)
381
        {
382
                final TypeKind tk1 = type1.kind();
383
                final TypeKind tk2 = type2.kind();
384

    
385
                if (tk1 != tk2)
386
                        throw new ArgumentException("Types need to be equal");
387

    
388
                switch (tk1)
389
                {
390
                        case Any:
391
                                return false;
392
                        case IntType:
393
                                final IntType Int1 = (IntType)type1;
394
                                final IntType Int2 = (IntType)type2;
395
                                return Int1.rangeLow() > Int2.rangeLow() ||
396
                                        Int1.rangeHigh() < Int2.rangeHigh();
397
                        case BoolType:
398
                                return false;
399
                        case FloatType:
400
                                final FloatType Float1 = (FloatType)type1;
401
                                final FloatType Float2 = (FloatType)type2;
402
                                return Float1.low() > Float2.low()
403
                                        || Float1.high() < Float2.high()
404
                                        || Float1.precision() > Float2.precision();
405
                        case EnumeratedType:
406
                                return false;
407
                        case ListType:
408
                                final ListType listt1 = (ListType)type1;
409
                                final ListType listt2 = (ListType)type2;
410
                                return (listt1.maxNumberOfElements() < listt2.maxNumberOfElements()) ||
411
                                        UlyssesType.FirstTypeLessRange(listt1.innerType(), listt2.innerType());
412
                        case MapType:
413
                                final MapType mapt1 = (MapType)type1;
414
                                final MapType mapt2 = (MapType)type2;
415
                                return (mapt1.maxNumberOfElements() < mapt2.maxNumberOfElements()) ||
416
                                        UlyssesType.FirstTypeLessRange(mapt1.fromType(), mapt2.fromType()) ||
417
                                        UlyssesType.FirstTypeLessRange(mapt1.toType(), mapt2.toType());
418
                        case QrType:
419
                                return false;
420
                        case TupleType:
421
                                final TupleType tuplet1 = (TupleType)type1;
422
                                final TupleType tuplet2 = (TupleType)type2;
423
                                if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
424
                                        return false;
425
                                final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator();
426
                                final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator();
427
                                while (innert1.hasNext())
428
                                {
429
                                        if (UlyssesType.FirstTypeLessRange(innert1.next(), innert2.next()))
430
                                                return true;
431
                                }
432
                                return false;
433
                        case OoActionSystemType:
434
                                return false;
435
                        case OpaqueType:
436
                                assert(false);
437
                                return false;
438
                        default:
439
                                throw new NotImplementedException();
440
                }
441
        }
442

    
443
        public static boolean TypeEqualByKind(UlyssesType type1, UlyssesType type2)
444
        {
445
                if ((type1 == null) || (type2 == null))
446
                        return false;
447

    
448
                final TypeKind tk1 = type1.kind();
449
                final TypeKind tk2 = type2.kind();
450

    
451
                // if of different kind, then return false..
452
                if (tk1 != tk2)
453
                        return false;
454

    
455
                // if same kind, make a rigorous check
456
                switch (tk1)
457
                {
458
                        case Any:
459
                                return true;
460

    
461
                        case IntType:
462
                        case BoolType:
463
                        case FloatType:
464
                                return true;
465
                        case EnumeratedType:
466
                                return type1 == type2; // ref equals
467
                        case ListType:
468
                                final ListType listt1 = (ListType)type1;
469
                                final ListType listt2 = (ListType)type2;
470
                                return UlyssesType.TypeEqualByKind(listt1.innerType(), listt2.innerType());
471
                        case MapType:
472
                                final MapType mapt1 = (MapType)type1;
473
                                final MapType mapt2 = (MapType)type2;
474
                                return UlyssesType.TypeEqualByKind(mapt1.fromType(), mapt2.fromType()) &&
475
                                        UlyssesType.TypeEqualByKind(mapt1.toType(), mapt2.toType());
476
                        case QrType:
477
                                final QrType qr1 = (QrType)type1;
478
                                final QrType qr2 = (QrType)type2;
479
                                return qr1 == qr2; // ref equals
480
                        case TupleType:
481
                                final TupleType tuplet1 = (TupleType)type1;
482
                                final TupleType tuplet2 = (TupleType)type2;
483
                                if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
484
                                        return false;
485
                                final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator();
486
                                final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator();
487
                                while (innert1.hasNext())
488
                                {
489
                                        if (!UlyssesType.TypeEqualByKind(innert1.next(), innert2.next()))
490
                                                return false;
491
                                }
492
                                return true;
493
                        case OoActionSystemType:
494
                                return type1 == type2; // ref equ.
495
                        case OpaqueType:
496
                                assert(false);
497
                                return false;
498
                        default:
499
                                throw new NotImplementedException();
500
                }
501
        }
502

    
503

    
504
        public static boolean TypeEqual(UlyssesType type1, UlyssesType type2)
505
        {
506
                // this will also work with opaque types...
507
                while (type1 instanceof OpaqueType)
508
                        type1 = ((OpaqueType)type1).resolvedType();
509
                while (type2 instanceof OpaqueType)
510
                        type2 = ((OpaqueType)type2).resolvedType();
511

    
512
                if ((type1 == null) || (type2 == null))
513
                        return false;
514

    
515
                final TypeKind tk1 = type1.kind();
516
                final TypeKind tk2 = type2.kind();
517

    
518
                // if of different kind, then return false..
519
                if (tk1 != tk2)
520
                        return false;
521

    
522
                // if same kind, make a rigorous check
523
                switch (tk1)
524
                {
525
                        case IntType:
526
                                final IntType intt1 = (IntType)type1;
527
                                final IntType intt2 = (IntType)type2;
528
                                return intt1.rangeLow() == intt2.rangeLow() &&
529
                                        intt1.rangeHigh() == intt2.rangeHigh();
530
                        case BoolType:
531
                                return true;
532
                        case FloatType:
533
                                final FloatType floatt1 = (FloatType)type1;
534
                                final FloatType floatt2 = (FloatType)type2;
535
                                return floatt1.low() == floatt2.low() &&
536
                                        floatt1.high() == floatt2.high() &&
537
                                        floatt1.precision() == floatt2.precision();
538
                        case EnumeratedType:
539
                                return type1 == type2; // ref equ
540
                        case ListType:
541
                                final ListType listt1 = (ListType)type1;
542
                                final ListType listt2 = (ListType)type2;
543
                                // an empty list can be of any type..
544
                                /*if ((listt1.innerType.kind == TypeKind.Null) || (listt2.innerType.kind == TypeKind.Null))
545
                                        return true;
546
                                else*/
547
                                return UlyssesType.TypeEqual(listt1.innerType(), listt2.innerType()) &&
548
                                                listt1.maxNumberOfElements() == listt2.maxNumberOfElements(); // need this because of covertype
549
                        case MapType:
550
                                final MapType mapt1 = (MapType)type1;
551
                                final MapType mapt2 = (MapType)type2;
552
                                return UlyssesType.TypeEqual(mapt1.fromType(), mapt2.fromType()) &&
553
                                        UlyssesType.TypeEqual(mapt1.toType(), mapt2.toType()) &&
554
                                        mapt1.maxNumberOfElements() == mapt2.maxNumberOfElements(); // need this because of covertype
555
                        case QrType:
556
                                final QrType qr1 = (QrType)type1;
557
                                final QrType qr2 = (QrType)type2;
558
                                return qr1 == qr2; // ref equ.
559
                        case TupleType:
560
                                final TupleType tuplet1 = (TupleType)type1;
561
                                final TupleType tuplet2 = (TupleType)type2;
562
                                if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
563
                                        return false;
564
                                final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator();
565
                                final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator();
566
                                while (innert1.hasNext())
567
                                {
568
                                        if (!UlyssesType.TypeEqual(innert1.next(), innert2.next()))
569
                                                return false;
570
                                }
571
                                return true;
572
                        case OoActionSystemType:
573
                                return type1 == type2; // ref equ. // || Covariance((OoActionSystemType)type1, (OoActionSystemType)type2);
574
                        case OpaqueType:
575
                                assert(false);
576
                                return false;
577
                        case Null:
578
                        case Any:
579
                                return true;
580
                        default:
581
                                throw new NotImplementedException();
582
                }
583
        }
584

    
585
        /// <summary>
586
        /// checks if type 2 is a desc. of type 1
587
        /// </summary>
588
        public static boolean Covariance(OoActionSystemType ooActionSystemType, OoActionSystemType ooActionSystemType_2)
589
        {
590
                // check if type 2 is a desc. of type 1
591
                while (ooActionSystemType != ooActionSystemType_2 && ooActionSystemType_2.baseType() != null) // ref equ.
592
                        ooActionSystemType_2 = ooActionSystemType_2.baseType();
593

    
594
                return ooActionSystemType == ooActionSystemType_2; // ref equ.
595
        }
596
}