root / trunk / compiler / ooasCompiler / src / org / momut / ooas / ast / types / Type.java @ 9
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 |
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(Type 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 |
default:
|
146 |
throw new NotImplementedException(); |
147 |
} |
148 |
} |
149 |
|
150 |
public static String Low(Type atype) |
151 |
{ |
152 |
switch (atype.kind())
|
153 |
{ |
154 |
case BoolType:
|
155 |
return "0"; |
156 |
case EnumeratedType:
|
157 |
return "0"; |
158 |
case IntType:
|
159 |
return Integer.toString(((IntType)atype).rangeLow()); |
160 |
case FloatType:
|
161 |
return Double.toString(((FloatType)atype).low()); |
162 |
// case TypeKind.QrType:
|
163 |
// return "0";
|
164 |
default:
|
165 |
throw new NotImplementedException(); |
166 |
} |
167 |
} |
168 |
|
169 |
|
170 |
/// <summary>
|
171 |
/// Returns a cover for two types (if possible).
|
172 |
/// note the cover type for two ints, floats, etc. will have max/min values
|
173 |
/// that reflect the maximum of the two operands.
|
174 |
/// </summary>
|
175 |
|
176 |
public static Type CoverType(Type type1, Type type2) |
177 |
{ |
178 |
/*first some sanity checks*/
|
179 |
if (type1 == null) |
180 |
throw new ArgumentException("type1 null"); |
181 |
if (type2 == null) |
182 |
throw new ArgumentException("type2 null"); |
183 |
|
184 |
if (type1.kind() == TypeKind.OpaqueType)
|
185 |
throw new ArgumentException("type1 opaque type"); |
186 |
if (type2.kind() == TypeKind.OpaqueType)
|
187 |
throw new ArgumentException("type2 opaque type"); |
188 |
|
189 |
if (type1 == type2)
|
190 |
return type1;
|
191 |
if (Type.TypeEqual(type1, type2)) |
192 |
return type1;
|
193 |
|
194 |
final TypeKind tk1 = type1.kind();
|
195 |
final TypeKind tk2 = type2.kind();
|
196 |
|
197 |
|
198 |
|
199 |
if (tk1 != tk2)
|
200 |
{ |
201 |
// the only notion we support here is int->float and valenum -> int
|
202 |
if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
|
203 |
&& (tk1 == TypeKind.FloatType || tk2 == TypeKind.FloatType)) |
204 |
{ |
205 |
final IntType aInt = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
|
206 |
final FloatType aFloat = tk1 == TypeKind.IntType ? (FloatType)type2 : (FloatType)type1;
|
207 |
|
208 |
final double low = aInt.rangeLow() < aFloat.low() ? (double)aInt.rangeLow() : aFloat.low(); |
209 |
final double high = aInt.rangeHigh() < aFloat.high() ? aFloat.high() : (double)aInt.rangeHigh(); |
210 |
final double precision = aFloat.precision() > 1 ? 1.0 : aFloat.precision(); |
211 |
|
212 |
return new FloatType(low, high, precision, null); |
213 |
|
214 |
} |
215 |
else if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType) |
216 |
&& (tk1 == TypeKind.EnumeratedType || tk2 == TypeKind.EnumeratedType)) |
217 |
{ |
218 |
final IntType intt1 = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
|
219 |
final EnumType anEnum = tk1 == TypeKind.IntType ? (EnumType)type2 : (EnumType)type1;
|
220 |
|
221 |
if (anEnum instanceof ValuedEnumType) |
222 |
{ |
223 |
final IntType intt2 = ((ValuedEnumType)anEnum).getIntType();
|
224 |
final int low = intt1.rangeLow() < intt2.rangeLow() ? intt1.rangeLow() : intt2.rangeLow(); |
225 |
final int high = intt1.rangeHigh() > intt2.rangeHigh() ? intt1.rangeHigh() : intt2.rangeHigh(); |
226 |
return new IntType(low, high, null); |
227 |
} |
228 |
else
|
229 |
return null; |
230 |
} |
231 |
else if (tk1 == TypeKind.Any || tk2 == TypeKind.Any) |
232 |
{ |
233 |
final AnyType freeVar = tk1 == TypeKind.Any ? (AnyType)type1 : (AnyType)type2;
|
234 |
final Type fixedType = tk1 == TypeKind.Any ? type2 : type1; |
235 |
final Type newcover = freeVar.VariableIdentifier().type().kind() == TypeKind.Any |
236 |
? fixedType : CoverType(fixedType, freeVar.VariableIdentifier().type()); |
237 |
freeVar.VariableIdentifier().SetType(newcover); |
238 |
return newcover;
|
239 |
} |
240 |
else if (tk1 == TypeKind.OoActionSystemType && tk2 == TypeKind.Null) |
241 |
{ |
242 |
return type1;
|
243 |
} |
244 |
else if (tk2 == TypeKind.OoActionSystemType && tk1 == TypeKind.Null) |
245 |
{ |
246 |
return type2;
|
247 |
} |
248 |
|
249 |
else
|
250 |
return null; |
251 |
} |
252 |
else
|
253 |
{ |
254 |
switch (tk1)
|
255 |
{ |
256 |
case Any:
|
257 |
return type1;
|
258 |
|
259 |
case IntType:
|
260 |
final IntType intt1 = (IntType)type1;
|
261 |
final IntType intt2 = (IntType)type2;
|
262 |
final int low = intt1.rangeLow() < intt2.rangeLow() ? intt1.rangeLow() : intt2.rangeLow(); |
263 |
final int high = intt1.rangeHigh() > intt2.rangeHigh() ? intt1.rangeHigh() : intt2.rangeHigh(); |
264 |
return new IntType(low, high, null); |
265 |
case BoolType:
|
266 |
return type1;
|
267 |
case FloatType:
|
268 |
final FloatType floatt1 = (FloatType)type1;
|
269 |
final FloatType floatt2 = (FloatType)type2;
|
270 |
final double flow = floatt1.low() < floatt2.low() ? floatt1.low() : floatt2.low(); |
271 |
final double fhigh = floatt1.high() > floatt2.high() ? floatt1.high() : floatt2.high(); |
272 |
final double fprec = floatt1.precision() < floatt2.precision() ? floatt1.precision() : floatt2.precision(); |
273 |
return new FloatType(flow, fhigh, fprec, null); |
274 |
case EnumeratedType:
|
275 |
return null; |
276 |
case ListType:
|
277 |
final ListType listt1 = (ListType)type1;
|
278 |
final ListType listt2 = (ListType)type2;
|
279 |
int maxelems = listt1.maxNumberOfElements() > listt2.maxNumberOfElements() ?
|
280 |
listt1.maxNumberOfElements() : listt2.maxNumberOfElements(); |
281 |
// empty lists lack type, so take the other one
|
282 |
if ((listt1.innerType().kind() == TypeKind.Null) && (listt2.innerType().kind() != TypeKind.Null))
|
283 |
return listt2;
|
284 |
else if ((listt2.innerType().kind() == TypeKind.Null) && (listt1.innerType().kind() != TypeKind.Null)) |
285 |
return listt1;
|
286 |
else if (listt1.innerType().kind() == TypeKind.Null && listt2.innerType().kind() == TypeKind.Null) |
287 |
return listt1;
|
288 |
else
|
289 |
{ |
290 |
final Type subtype = Type.CoverType(listt1.innerType(), listt2.innerType()); |
291 |
if (subtype != null) |
292 |
return new ListType(subtype, maxelems, null); |
293 |
else
|
294 |
return null; |
295 |
} |
296 |
case MapType:
|
297 |
final MapType mapt1 = (MapType)type1;
|
298 |
final MapType mapt2 = (MapType)type2;
|
299 |
// empty maps lack type, so take the other one.
|
300 |
if ((mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null)
|
301 |
&& (mapt2.fromType().kind() != TypeKind.Null && mapt2.toType().kind() != TypeKind.Null)) |
302 |
return mapt2;
|
303 |
else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null) |
304 |
&& (mapt1.fromType().kind() != TypeKind.Null && mapt1.toType().kind() != TypeKind.Null)) |
305 |
return mapt1;
|
306 |
else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null) |
307 |
&& (mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null)) |
308 |
return mapt1;
|
309 |
else
|
310 |
{ |
311 |
final Type sub1 = Type.CoverType(mapt1.fromType(), mapt2.fromType()); |
312 |
final Type sub2 = Type.CoverType(mapt2.toType(), mapt2.toType()); |
313 |
maxelems = mapt1.maxNumberOfElements() > mapt2.maxNumberOfElements() ? |
314 |
mapt1.maxNumberOfElements() : mapt2.maxNumberOfElements(); |
315 |
if (sub1 != null && sub2 != null) |
316 |
return new MapType(sub1, sub2, maxelems, null); |
317 |
else
|
318 |
return null; |
319 |
} |
320 |
case QrType:
|
321 |
return null; /*if refs are equal, we do not reach this statement! see above..*/ |
322 |
case TupleType:
|
323 |
final TupleType tuplet1 = (TupleType)type1;
|
324 |
final TupleType tuplet2 = (TupleType)type2;
|
325 |
final TupleType result = new TupleType(null); |
326 |
final Iterator<Type> innert1 = tuplet1.innerTypes().iterator(); |
327 |
final Iterator<Type> innert2 = tuplet2.innerTypes().iterator(); |
328 |
while (innert1.hasNext())
|
329 |
{ |
330 |
final Type newinner = Type.CoverType(innert1.next(), innert2.next()); |
331 |
if (newinner == null) |
332 |
return null; |
333 |
result.AddType(newinner); |
334 |
} |
335 |
return result;
|
336 |
case OoActionSystemType:
|
337 |
if (type1.kind() == TypeKind.Null && type2.kind() != TypeKind.Null)
|
338 |
return type2;
|
339 |
else if (type2.kind() == TypeKind.Null && type1.kind() != TypeKind.Null) |
340 |
return type1;
|
341 |
else if (type1.kind() == TypeKind.Null && type2.kind() == TypeKind.Null) |
342 |
return type2;
|
343 |
else if (type1 == type2) // ref equals! |
344 |
return type1;
|
345 |
else
|
346 |
return ClassBaseType((OoActionSystemType)type1, (OoActionSystemType)type2);
|
347 |
case OpaqueType:
|
348 |
assert(false); |
349 |
return null; |
350 |
default:
|
351 |
throw new NotImplementedException(); |
352 |
} |
353 |
} |
354 |
} |
355 |
|
356 |
private static Type ClassBaseType(OoActionSystemType type1, OoActionSystemType type2) |
357 |
{ |
358 |
// this is rather inefficient.. should be done differently
|
359 |
final OoActionSystemType typea = type1;
|
360 |
final OoActionSystemType typeb = type2;
|
361 |
OoActionSystemType basea = type1; |
362 |
OoActionSystemType baseb = type2; |
363 |
while (basea != null) |
364 |
{ |
365 |
if (basea == typeb) // ref equals |
366 |
return basea;
|
367 |
basea = basea.baseType(); |
368 |
} |
369 |
while (baseb != null) |
370 |
{ |
371 |
if (baseb == typea) // ref equals |
372 |
return baseb;
|
373 |
baseb = baseb.baseType(); |
374 |
} |
375 |
return null; |
376 |
} |
377 |
|
378 |
public static boolean FirstTypeLessRange(Type type1, Type type2) |
379 |
{ |
380 |
final TypeKind tk1 = type1.kind();
|
381 |
final TypeKind tk2 = type2.kind();
|
382 |
|
383 |
if (tk1 != tk2)
|
384 |
throw new ArgumentException("Types need to be equal"); |
385 |
|
386 |
switch (tk1)
|
387 |
{ |
388 |
case Any:
|
389 |
return false; |
390 |
case IntType:
|
391 |
final IntType Int1 = (IntType)type1;
|
392 |
final IntType Int2 = (IntType)type2;
|
393 |
return Int1.rangeLow() > Int2.rangeLow() ||
|
394 |
Int1.rangeHigh() < Int2.rangeHigh(); |
395 |
case BoolType:
|
396 |
return false; |
397 |
case FloatType:
|
398 |
final FloatType Float1 = (FloatType)type1;
|
399 |
final FloatType Float2 = (FloatType)type2;
|
400 |
return Float1.low() > Float2.low()
|
401 |
|| Float1.high() < Float2.high() |
402 |
|| Float1.precision() > Float2.precision(); |
403 |
case EnumeratedType:
|
404 |
return false; |
405 |
case ListType:
|
406 |
final ListType listt1 = (ListType)type1;
|
407 |
final ListType listt2 = (ListType)type2;
|
408 |
return (listt1.maxNumberOfElements() < listt2.maxNumberOfElements()) ||
|
409 |
Type.FirstTypeLessRange(listt1.innerType(), listt2.innerType());
|
410 |
case MapType:
|
411 |
final MapType mapt1 = (MapType)type1;
|
412 |
final MapType mapt2 = (MapType)type2;
|
413 |
return (mapt1.maxNumberOfElements() < mapt2.maxNumberOfElements()) ||
|
414 |
Type.FirstTypeLessRange(mapt1.fromType(), mapt2.fromType()) ||
|
415 |
Type.FirstTypeLessRange(mapt1.toType(), mapt2.toType());
|
416 |
case QrType:
|
417 |
return false; |
418 |
case TupleType:
|
419 |
final TupleType tuplet1 = (TupleType)type1;
|
420 |
final TupleType tuplet2 = (TupleType)type2;
|
421 |
if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
|
422 |
return false; |
423 |
final Iterator<Type> innert1 = tuplet1.innerTypes().iterator(); |
424 |
final Iterator<Type> innert2 = tuplet2.innerTypes().iterator(); |
425 |
while (innert1.hasNext())
|
426 |
{ |
427 |
if (Type.FirstTypeLessRange(innert1.next(), innert2.next())) |
428 |
return true; |
429 |
} |
430 |
return false; |
431 |
case OoActionSystemType:
|
432 |
return false; |
433 |
case OpaqueType:
|
434 |
assert(false); |
435 |
return false; |
436 |
default:
|
437 |
throw new NotImplementedException(); |
438 |
} |
439 |
} |
440 |
|
441 |
public static boolean TypeEqualByKind(Type type1, Type type2) |
442 |
{ |
443 |
if ((type1 == null) || (type2 == null)) |
444 |
return false; |
445 |
|
446 |
final TypeKind tk1 = type1.kind();
|
447 |
final TypeKind tk2 = type2.kind();
|
448 |
|
449 |
// if of different kind, then return false..
|
450 |
if (tk1 != tk2)
|
451 |
return false; |
452 |
|
453 |
// if same kind, make a rigorous check
|
454 |
switch (tk1)
|
455 |
{ |
456 |
case Any:
|
457 |
return true; |
458 |
|
459 |
case IntType:
|
460 |
case BoolType:
|
461 |
case FloatType:
|
462 |
return true; |
463 |
case EnumeratedType:
|
464 |
return type1 == type2; // ref equals |
465 |
case ListType:
|
466 |
final ListType listt1 = (ListType)type1;
|
467 |
final ListType listt2 = (ListType)type2;
|
468 |
return Type.TypeEqualByKind(listt1.innerType(), listt2.innerType()); |
469 |
case MapType:
|
470 |
final MapType mapt1 = (MapType)type1;
|
471 |
final MapType mapt2 = (MapType)type2;
|
472 |
return Type.TypeEqualByKind(mapt1.fromType(), mapt2.fromType()) && |
473 |
Type.TypeEqualByKind(mapt1.toType(), mapt2.toType());
|
474 |
case TupleType:
|
475 |
final TupleType tuplet1 = (TupleType)type1;
|
476 |
final TupleType tuplet2 = (TupleType)type2;
|
477 |
if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
|
478 |
return false; |
479 |
final Iterator<Type> innert1 = tuplet1.innerTypes().iterator(); |
480 |
final Iterator<Type> innert2 = tuplet2.innerTypes().iterator(); |
481 |
while (innert1.hasNext())
|
482 |
{ |
483 |
if (!Type.TypeEqualByKind(innert1.next(), innert2.next())) |
484 |
return false; |
485 |
} |
486 |
return true; |
487 |
case OoActionSystemType:
|
488 |
return type1 == type2; // ref equ. |
489 |
case OpaqueType:
|
490 |
assert(false); |
491 |
return false; |
492 |
default:
|
493 |
throw new NotImplementedException(); |
494 |
} |
495 |
} |
496 |
|
497 |
|
498 |
public static boolean TypeEqual(Type type1, Type type2) |
499 |
{ |
500 |
// this will also work with opaque types...
|
501 |
while (type1 instanceof OpaqueType) |
502 |
type1 = ((OpaqueType)type1).resolvedType(); |
503 |
while (type2 instanceof OpaqueType) |
504 |
type2 = ((OpaqueType)type2).resolvedType(); |
505 |
|
506 |
if ((type1 == null) || (type2 == null)) |
507 |
return false; |
508 |
|
509 |
final TypeKind tk1 = type1.kind();
|
510 |
final TypeKind tk2 = type2.kind();
|
511 |
|
512 |
// if of different kind, then return false..
|
513 |
if (tk1 != tk2)
|
514 |
return false; |
515 |
|
516 |
// if same kind, make a rigorous check
|
517 |
switch (tk1)
|
518 |
{ |
519 |
case IntType:
|
520 |
final IntType intt1 = (IntType)type1;
|
521 |
final IntType intt2 = (IntType)type2;
|
522 |
return intt1.rangeLow() == intt2.rangeLow() &&
|
523 |
intt1.rangeHigh() == intt2.rangeHigh(); |
524 |
case BoolType:
|
525 |
return true; |
526 |
case FloatType:
|
527 |
final FloatType floatt1 = (FloatType)type1;
|
528 |
final FloatType floatt2 = (FloatType)type2;
|
529 |
return floatt1.low() == floatt2.low() &&
|
530 |
floatt1.high() == floatt2.high() && |
531 |
floatt1.precision() == floatt2.precision(); |
532 |
case EnumeratedType:
|
533 |
return type1 == type2; // ref equ |
534 |
case ListType:
|
535 |
final ListType listt1 = (ListType)type1;
|
536 |
final ListType listt2 = (ListType)type2;
|
537 |
// an empty list can be of any type..
|
538 |
/*if ((listt1.innerType.kind == TypeKind.Null) || (listt2.innerType.kind == TypeKind.Null))
|
539 |
return true;
|
540 |
else*/
|
541 |
return Type.TypeEqual(listt1.innerType(), listt2.innerType()) && |
542 |
listt1.maxNumberOfElements() == listt2.maxNumberOfElements(); // need this because of covertype
|
543 |
case MapType:
|
544 |
final MapType mapt1 = (MapType)type1;
|
545 |
final MapType mapt2 = (MapType)type2;
|
546 |
return Type.TypeEqual(mapt1.fromType(), mapt2.fromType()) && |
547 |
Type.TypeEqual(mapt1.toType(), mapt2.toType()) &&
|
548 |
mapt1.maxNumberOfElements() == mapt2.maxNumberOfElements(); // need this because of covertype
|
549 |
case TupleType:
|
550 |
final TupleType tuplet1 = (TupleType)type1;
|
551 |
final TupleType tuplet2 = (TupleType)type2;
|
552 |
if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
|
553 |
return false; |
554 |
final Iterator<Type> innert1 = tuplet1.innerTypes().iterator(); |
555 |
final Iterator<Type> innert2 = tuplet2.innerTypes().iterator(); |
556 |
while (innert1.hasNext())
|
557 |
{ |
558 |
if (!Type.TypeEqual(innert1.next(), innert2.next())) |
559 |
return false; |
560 |
} |
561 |
return true; |
562 |
case OoActionSystemType:
|
563 |
return type1 == type2; // ref equ. // || Covariance((OoActionSystemType)type1, (OoActionSystemType)type2); |
564 |
case OpaqueType:
|
565 |
assert(false); |
566 |
return false; |
567 |
case Null:
|
568 |
case Any:
|
569 |
return true; |
570 |
default:
|
571 |
throw new NotImplementedException(); |
572 |
} |
573 |
} |
574 |
|
575 |
/// <summary>
|
576 |
/// checks if type 2 is a desc. of type 1
|
577 |
/// </summary>
|
578 |
public static boolean Covariance(OoActionSystemType ooActionSystemType, OoActionSystemType ooActionSystemType_2) |
579 |
{ |
580 |
// check if type 2 is a desc. of type 1
|
581 |
while (ooActionSystemType != ooActionSystemType_2 && ooActionSystemType_2.baseType() != null) // ref equ. |
582 |
ooActionSystemType_2 = ooActionSystemType_2.baseType(); |
583 |
|
584 |
return ooActionSystemType == ooActionSystemType_2; // ref equ. |
585 |
} |
586 |
} |