Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / ast / types / Type.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.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 Type 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 Type(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 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
        /**
122
         * returns the number of unique values of the type (2 for bool, etc..)
123
         */
124
        public int valueCount() {
125
                throw new NotImplementedException(); // must be overridden by child
126
        }
127

    
128
        public static String High(Type atype)
129
        {
130
                switch (atype.kind())
131
                {
132
                        case BoolType:
133
                                return "1";
134
                        case EnumeratedType:
135
                                return Integer.toString((((EnumType)atype).listOfEnumSymbols().size() - 1));
136
                        case IntType:
137
                                return Integer.toString(((IntType)atype).rangeHigh());
138
                        case FloatType:
139
                                return Double.toString(((FloatType)atype).high());
140
                        default:
141
                                throw new NotImplementedException();
142
                }
143
        }
144

    
145
        public static String Low(Type atype)
146
        {
147
                switch (atype.kind())
148
                {
149
                        case BoolType:
150
                                return "0";
151
                        case EnumeratedType:
152
                                return "0";
153
                        case IntType:
154
                                return Integer.toString(((IntType)atype).rangeLow());
155
                        case FloatType:
156
                                return Double.toString(((FloatType)atype).low());
157
//                        case TypeKind.QrType:
158
//                                return "0";
159
                        default:
160
                                throw new NotImplementedException();
161
                }
162
        }
163

    
164

    
165
        /// <summary>
166
        ///  Returns a cover for two types (if possible).
167
        ///  note the cover type for two ints, floats, etc. will have max/min values
168
        ///  that reflect the maximum of the two operands.
169
        /// </summary>
170

    
171
        public static Type CoverType(Type type1, Type type2)
172
        {
173
                /*first some sanity checks*/
174
                if (type1 == null)
175
                        throw new ArgumentException("type1 null");
176
                if (type2 == null)
177
                        throw new ArgumentException("type2 null");
178

    
179
                if (type1.kind() == TypeKind.OpaqueType)
180
                        throw new ArgumentException("type1 opaque type");
181
                if (type2.kind() == TypeKind.OpaqueType)
182
                        throw new ArgumentException("type2 opaque type");
183

    
184
                if (type1 == type2)
185
                        return type1;
186
                if (Type.TypeEqual(type1, type2))
187
                        return type1;
188

    
189
                final TypeKind tk1 = type1.kind();
190
                final TypeKind tk2 = type2.kind();
191

    
192

    
193

    
194
                if (tk1 != tk2)
195
                {
196
                        // the only notion we support here is int->float and valenum -> int
197
                        if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
198
                                        && (tk1 == TypeKind.FloatType || tk2 == TypeKind.FloatType))
199
                        {
200
                                final IntType aInt = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
201
                                final FloatType aFloat = tk1 == TypeKind.IntType ? (FloatType)type2 : (FloatType)type1;
202

    
203
                                final double low = aInt.rangeLow() < aFloat.low() ? (double)aInt.rangeLow() : aFloat.low();
204
                                final double high = aInt.rangeHigh() < aFloat.high() ? aFloat.high() : (double)aInt.rangeHigh();
205
                                final double precision = aFloat.precision() > 1 ? 1.0 : aFloat.precision();
206

    
207
                                return new FloatType(low, high, precision, null);
208

    
209
                        }
210
                        else if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
211
                                        && (tk1 == TypeKind.EnumeratedType || tk2 == TypeKind.EnumeratedType))
212
                        {
213
                                final IntType intt1 = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
214
                                final EnumType anEnum = tk1 == TypeKind.IntType ? (EnumType)type2 : (EnumType)type1;
215

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

    
244
                        else
245
                                return null;
246
                }
247
                else
248
                {
249
                        switch (tk1)
250
                        {
251
                                case Any:
252
                                        return type1;
253

    
254
                                case IntType:
255
                                        final IntType intt1 = (IntType)type1;
256
                                        final IntType intt2 = (IntType)type2;
257
                                        final int low = intt1.rangeLow() < intt2.rangeLow() ? intt1.rangeLow() : intt2.rangeLow();
258
                                        final int high = intt1.rangeHigh() > intt2.rangeHigh() ? intt1.rangeHigh() : intt2.rangeHigh();
259
                                        return new IntType(low, high, null);
260
                                case BoolType:
261
                                        return type1;
262
                                case FloatType:
263
                                        final FloatType floatt1 = (FloatType)type1;
264
                                        final FloatType floatt2 = (FloatType)type2;
265
                                        final double flow = floatt1.low() < floatt2.low() ? floatt1.low() : floatt2.low();
266
                                        final double fhigh = floatt1.high() > floatt2.high() ? floatt1.high() : floatt2.high();
267
                                        final double fprec = floatt1.precision() < floatt2.precision() ? floatt1.precision() : floatt2.precision();
268
                                        return new FloatType(flow, fhigh, fprec, null);
269
                                case EnumeratedType:
270
                                        return null;
271
                                case ListType:
272
                                        final ListType listt1 = (ListType)type1;
273
                                        final ListType listt2 = (ListType)type2;
274
                                        // empty lists lack type, so take the other one
275
                                        if ((listt1.innerType().kind() == TypeKind.Null) && (listt2.innerType().kind() != TypeKind.Null))
276
                                                return listt2;
277
                                        else if ((listt2.innerType().kind() == TypeKind.Null) && (listt1.innerType().kind() != TypeKind.Null))
278
                                                return listt1;
279
                                        else if (listt1.innerType().kind() == TypeKind.Null && listt2.innerType().kind() == TypeKind.Null)
280
                                                return listt1;
281
                                        else
282
                                        {
283
                                                /**
284
                                                 * A cover type of a list must not change the size of the inner type. Mostly what is
285
                                                 * allowed to change is the list length.
286
                                                 */
287
                                                final Type innerType1 = listt1.innerType();
288
                                                final Type innerType2 = listt2.innerType();
289
                                                Type resultInner = innerType1;
290
                                                final boolean castAllowed = TypeEqual(innerType1, innerType2)
291
                                                          ||     (resultInner = Type.CoverType(innerType1, innerType2)) != null;
292
                                                if (castAllowed){
293
                                                        final int maxelems = listt1.maxNumberOfElements() > listt2.maxNumberOfElements()
294
                                                                        ? listt1.maxNumberOfElements()
295
                                                                        : listt2.maxNumberOfElements();
296
                                                        return new ListType(resultInner, maxelems, null);
297
                                                } else
298
                                                        return null;
299

    
300
//                                                // The code blow allowed for bit-size changes of the inner type and is considered too
301
//                                                // liberal. If a deep cast is necessary, the user might want to do a fold operation
302
//                                                // instead..
303
//                                                final Type subtype = Type.CoverType(listt1.innerType(), listt2.innerType());
304
//                                                if (subtype != null)
305
//                                                        return new ListType(subtype, maxelems, null);
306
//                                                else
307
//                                                        return null;
308
                                        }
309
                                case MapType:
310
                                        final MapType mapt1 = (MapType)type1;
311
                                        final MapType mapt2 = (MapType)type2;
312
                                        // empty maps lack type, so take the other one.
313
                                        if ((mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null)
314
                                           && (mapt2.fromType().kind() != TypeKind.Null && mapt2.toType().kind() != TypeKind.Null))
315
                                                return mapt2;
316
                                        else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null)
317
                                           && (mapt1.fromType().kind() != TypeKind.Null && mapt1.toType().kind() != TypeKind.Null))
318
                                                return mapt1;
319
                                        else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null)
320
                                           && (mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null))
321
                                                return mapt1;
322
                                        else
323
                                        {
324
                                                final Type sub1 = Type.CoverType(mapt1.fromType(), mapt2.fromType());
325
                                                final Type sub2 = Type.CoverType(mapt2.toType(), mapt2.toType());
326
                                                final int maxelems = mapt1.maxNumberOfElements() > mapt2.maxNumberOfElements() ?
327
                                                        mapt1.maxNumberOfElements() : mapt2.maxNumberOfElements();
328
                                                if (sub1 != null && sub2 != null)
329
                                                        return new MapType(sub1, sub2, maxelems, null);
330
                                                else
331
                                                        return null;
332
                                        }
333
                                case TupleType:
334
                                        final TupleType tuplet1 = (TupleType)type1;
335
                                        final TupleType tuplet2 = (TupleType)type2;
336
                                        final TupleType result = new TupleType(null);
337
                                        final Iterator<Type> innert1 = tuplet1.innerTypes().iterator();
338
                                        final Iterator<Type> innert2 = tuplet2.innerTypes().iterator();
339
                                        while (innert1.hasNext())
340
                                        {
341
                                                final Type newinner = Type.CoverType(innert1.next(), innert2.next());
342
                                                if (newinner == null)
343
                                                        return null;
344
                                                result.AddType(newinner);
345
                                        }
346
                                        return result;
347
                                case OoActionSystemType:
348
                                        if (type1.kind() == TypeKind.Null && type2.kind() != TypeKind.Null)
349
                                                return type2;
350
                                        else if (type2.kind() == TypeKind.Null && type1.kind() != TypeKind.Null)
351
                                                return type1;
352
                                        else if (type1.kind() == TypeKind.Null && type2.kind() == TypeKind.Null)
353
                                                return type2;
354
                                        else if (type1 == type2) // ref equals!
355
                                                return type1;
356
                                        else
357
                                                return ClassBaseType((OoActionSystemType)type1, (OoActionSystemType)type2);
358
                                case OpaqueType:
359
                                        assert(false);
360
                                        return null;
361
                                default:
362
                                        throw new NotImplementedException();
363
                        }
364
                }
365
        }
366

    
367
        private static Type ClassBaseType(OoActionSystemType type1, OoActionSystemType type2)
368
        {
369
                // this is rather inefficient.. should be done differently
370
                final OoActionSystemType typea = type1;
371
                final OoActionSystemType typeb = type2;
372
                OoActionSystemType basea = type1;
373
                OoActionSystemType baseb = type2;
374
                while (basea != null)
375
                {
376
                        if (basea == typeb)  // ref equals
377
                                return basea;
378
                        basea = basea.baseType();
379
                }
380
                while (baseb != null)
381
                {
382
                        if (baseb == typea) // ref equals
383
                                return baseb;
384
                        baseb = baseb.baseType();
385
                }
386
                return null;
387
        }
388

    
389
        public static boolean FirstTypeLessRange(Type type1, Type type2)
390
        {
391
                final TypeKind tk1 = type1.kind();
392
                final TypeKind tk2 = type2.kind();
393

    
394
                if (tk1 != tk2)
395
                        throw new ArgumentException("Types need to be equal");
396

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

    
452
        public static boolean TypeEqualByKind(Type type1, Type type2)
453
        {
454
                if ((type1 == null) || (type2 == null))
455
                        return false;
456

    
457
                final TypeKind tk1 = type1.kind();
458
                final TypeKind tk2 = type2.kind();
459

    
460
                // if of different kind, then return false..
461
                if (tk1 != tk2)
462
                        return false;
463

    
464
                // if same kind, make a rigorous check
465
                switch (tk1)
466
                {
467
                        case Any:
468
                                return true;
469

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

    
510

    
511
        public static boolean TypeEqual(Type type1, Type type2)
512
        {
513
                // this will also work with opaque types...
514
                while (type1 instanceof OpaqueType)
515
                        type1 = ((OpaqueType)type1).resolvedType();
516
                while (type2 instanceof OpaqueType)
517
                        type2 = ((OpaqueType)type2).resolvedType();
518

    
519
                if ((type1 == null) || (type2 == null))
520
                        return false;
521

    
522
                final TypeKind tk1 = type1.kind();
523
                final TypeKind tk2 = type2.kind();
524

    
525
                // if of different kind, then return false..
526
                if (tk1 != tk2)
527
                        return false;
528

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

    
590
        /// <summary>
591
        /// checks if type 2 is a desc. of type 1
592
        /// </summary>
593
        public static boolean Covariance(OoActionSystemType ooActionSystemType, OoActionSystemType ooActionSystemType_2)
594
        {
595
                // check if type 2 is a desc. of type 1
596
                while (ooActionSystemType != ooActionSystemType_2 && ooActionSystemType_2.baseType() != null) // ref equ.
597
                        ooActionSystemType_2 = ooActionSystemType_2.baseType();
598

    
599
                return ooActionSystemType == ooActionSystemType_2; // ref equ.
600
        }
601
}